実行時に既知の型がパラメーターなしのコンストラクターを提供するかどうかを確認したいと思います。 Type
クラスは有望なものをもたらさなかったので、リフレクションを使用する必要があると思いますか?
Type
クラスisリフレクションです。できるよ:
_Type theType = myobject.GetType(); // if you have an instance
// or
Type theType = typeof(MyObject); // if you know the type
var constructor = theType.GetConstructor(Type.EmptyTypes);
_
パラメーターなしのコンストラクターが存在しない場合はnullを返します。
プライベートコンストラクターも検索する場合は、少し長いものを使用します。
_var constructor = theType.GetConstructor(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null, Type.EmptyTypes, null);
_
値の型には注意事項があります。これは、 デフォルトのコンストラクタを持つことは許可されていません です。 _Type.IsValueType
_ プロパティを使用して値タイプがあるかどうかを確認し、 Activator.CreateInstance(Type)
;を使用してインスタンスを作成できます。
type.GetConstructor(Type.EmptyTypes) != null
struct
sでは失敗します。拡張する方が良い:
public static bool HasDefaultConstructor(this Type t)
{
return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
enum
sでもデフォルトのパラメーターなしのコンストラクターがあるため成功します。また、リフレクションの呼び出しが行われないため、値型の速度がわずかに向上します。
はい、Reflectionを使用する必要があります。ただし、GetType()
を使用する場合は、すでにそれを行っています。
何かのようなもの:
var t = x.GetType();
var c = t.GetConstructor(new Type[0]);
if (c != null) ...
これは動作するはずです:
myClass.GetType().GetConstructors()
.All(c=>c.GetParameters().Length == 0)
状況に応じて、ジェネリック型の制限を使用することもできます。
public void DoSomethingWith<T>(T myObject) where T:new() {...}
上記のメソッド宣言は、パラメーターのないコンストラクターでインスタンス化できる任意のオブジェクトにパラメータータイプを制限します。ここでの利点は、コンパイラがパラメータレスコンストラクターを持たないクラスでメソッドを使用しようとする試みをキャッチすることです。そのため、コンパイル時に型がSOMEWHEREであることがわかっている限り、これは動作し、以前の問題。
もちろん、型が実行時にのみ実際に知られている場合(つまり、Activator.CreateInstance()を使用して文字列または構築された型に基づいてオブジェクトをインスタンス化する場合)、これは役に立ちません。私は通常、絶対的な最後のオプションとしてリフレクションを使用します。動的な土地に行ったら、動的な土地にとどまる必要があるためです。通常、何かを動的にインスタンス化してから静的に処理を開始することは困難であり、さらに面倒です。
「公式」バージョンに興味がある人は、 。NET Reflector で次のことが見つかりました。
from:System.Activities.Presentation.TypeUtilities
inSystem.Activities.Presentation.dll、Version = 4.0.0.0
public static bool CanCreateInstanceUsingDefaultConstructor(this Type t) =>
t.IsValueType || !t.IsAbstract && t.GetConstructor(Type.EmptyTypes) != null;
t.IsAbstract
のチェックに注意してください。これは、このページのどこにも記載されていません。
スタックフレームを1つずつ微最適化する場合は、次のようにGetConstructor
コールアウトを展開することもできます。
…t.GetConstructor(BindingFlags.Public|BindingFlags.Instance, null, Type.EmptyTypes, null)…
はい、反射を使用する必要があります。
object myObject = new MyType();
Type type = myObject.GetType();
ConstructorInfo conInfo = type.GetConstructor(new Type[0]);
onlyオプションのパラメーターを持つコンストラクターを、真のパラメーターレスコンストラクターと同じように数える必要がありました。これをする:
myClass.GetType().GetConstructors()
.All(c => c.GetParameters().Length == 0 || c.GetParameters().All(p => p.IsOptional))