2011-01-13 5 views
78

私は、実行時に知られている型がパラメータのないコンストラクタを提供しているかどうかチェックしたいと思います。 Typeクラスは有望なものを得られなかったので、私はリフレクションを使用しなければならないと仮定していますか?型がパラメータのないコンストラクタを提供するかどうかを確認するにはどうすればよいですか?

+0

私はそうだと思います – kenny

+2

サイドローズ:パラメータのないコンストラクタには一般的な制約があります。 – CodesInChaos

+1

は、タイプ**のみ**がパラメータのないコンストラクタを提供するか、それとも全く提供しないかという疑問です。 – BrokenGlass

答えて

132

Typeクラス反映したものです。次のようにすることができます。

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); 

aren't allowed to have a default constructor値型、のための注意点はあります。 Type.IsValueTypeプロパティを使用して値の型があるかどうかを確認し、Activator.CreateInstance(Type)を使用してインスタンスを作成します。

+2

これはプライベートctors fyiを見つけることはありません –

+2

これはまた値の種類のために働きません。 – leppie

+2

上記のコメントがあります。 –

12

はい、Reflectionを使用する必要があります。

var t = x.GetType(); 
var c = t.GetConstructor(new Type[0]); 
if (c != null) ... 
6

これは動作するはずです::しかし、あなたはすでにあなたのようなGetType()

何かを使用する場合があることを行う

myClass.GetType().GetConstructors() 
        .All(c=>c.GetParameters().Length == 0) 
+1

私が言ったことではありませんが、削除しないでください - それは関連する問題と素晴らしい情報です。 – mafu

1

はい、反射を使用する必要があります。

object myObject = new MyType(); 
Type type = myObject.GetType(); 
ConstructorInfo conInfo = type.GetConstructor(new Type[0]); 
3

あなたの状況に応じて、あなたはまた、ジェネリック型の制約を使用することができます。

public void DoSomethingWith<T>(T myObject) where T:new() {...} 

上記のメソッドの宣言は、パラメータなしのコンストラクタでインスタンス化することができる任意のオブジェクトにパラメータタイプを制限します。ここでの利点は、コンパイラがパラメータのないコンストラクタを持たないクラスでメソッドを使用しようとする試みをキャッチすることです。コンパイル時にタイプが分かっている限り、これはうまく動作します。問題は早い。

タイプが実際には実行時にしかわからない場合(つまり、Activator.CreateInstance()を使用して文字列や構造化タイプに基づいてオブジェクトをインスタンス化する場合)、これは役に立ちません。私は一般にリフレクションを絶対最後のオプションとして使用します。なぜなら、一度あなたがダイナミックな土地に行くと、あなたはダイナミックな土地に留まる必要があるからです。動的にインスタンス化してから静的に処理するのは、通常は難しく、あるいは面倒です。

+0

実際には、静的および動的呼び出しの土地を結ぶのに非常に有用なパターンがあります。 'EqualityComparer.Default ']。与えられた型 'T'に対しては、必要な制約条件を満たすためにインスタンス型が静的に知られているオブジェクトを構築するためにReflectionを1回使用するだけでよく、制約を課すことのないフィールドに参照を格納する必要があります。発信者が提供できない場合があります。 – supercat

10
type.GetConstructor(Type.EmptyTypes) != null 

は、structで失敗します。より良いそれを拡張します

public static bool HasDefaultConstructor(this Type t) 
{ 
    return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null; 
} 

は成功してもenum sがデフォルトパラメータなしのコンストラクタを持っているので。また、リフレクションコールが行われていないため、値型の速度が若干上がります。

1

のみのコンストラクタを計算する必要がありましたオプションパラメータは、実際のパラメータなしコンストラクタと同じです。これを行うには:

myClass.GetType().GetConstructors() 
    .All(c => c.GetParameters().Length == 0 || c.GetParameters().All(p => p.IsOptional)) 
関連する問題