2009-08-15 6 views
37

私は与えられたタイプのデフォルト値を返し、メソッドがジェネリックである方法をしたい場合は、私はそうのようなデフォルト値を返すことができます型がSystem.Typeとしてのみ知られている場合、型のデフォルト値を取得する方法は?

public static T GetDefaultValue() 
{ 
    return default(T); 
} 

は、私はケースに似た何かを行うことができ、私は唯一のように型を持ちますSystem.Typeオブジェクト?

public static object GetDefaultValue(Type type) 
{ 
    //??? 
} 

答えて

62

実際に値の型(参照型はnullのみ)について心配する必要があるので、Activator.CreateInstanceを使用してデフォルトのコンストラクタを呼び出すことができます。

public static object GetDefaultValue(Type type) { 
    return type.IsValueType ? Activator.CreateInstance(type) : null; 
} 

編集:Jonは正しいです。 IsClassは網羅的ではありません。typeがインタフェースの場合はFalseを返します。

+18

インターフェイスに対処するために、!type.IsValueTypeを使用する方が便利です。 –

+0

ありがとうございました!それが私が探していたものです! –

1

ジェネリックがなければ、あなたはタイプがパラメータなしのコンストラクタを持っていることを保証することはできませんが、リフレクションを使用して1を検索することができます。

public static object GetDefaultValue(Type type) 
{ 
    ConstructorInfo ci = type.GetConstructor(new Type[] {}); 
    return ci.Invoke(new object[] {}); 
} 

私はコンソールアプリでこれを試してみましたが、それそれがクラスであると仮定して、クラス—の「デフォルト」インスタンスを返します。参照型でも動作する必要がある場合は、追加のテクニックが必要です。

+3

リファレンスタイプのデフォルト値はnullであり、クラスのインスタンスではありません。 GetDefault(T)が可能な限りインスタンスを作成しようとする間、GetDefault(T)はnullを返します。間違っています。テクニックは役に立たないわけではありませんが、T:new(){return new T();} "というタイプのメソッドのような" T GetInstance(T) "のようなものです。 – JohannesH

+0

私はあなたが何を意味するかを見ます。訂正ありがとう! – harpo

+0

あなたの答えは非常に便利です。 – rolls

7

ここで私はそれを普通にやっています。これにより、 'IsValueType'全体、またはコンストラクタの検索が完全に回避されます。

public static object MakeDefault(this Type type) 
{ 
    var makeDefault = typeof(ExtReflection).GetMethod("MakeDefaultGeneric"); 
    var typed = makeDefault.MakeGenericMethod(type); 
    return typed.Invoke(null, new object[] { }); 
} 

public static T MakeDefaultGeneric<T>() 
{ 
    return default(T); 
} 
+0

これがMark Brackettの回答とどのように違っているか/良い/悪いか説明できますか? – rolls

+0

私はそれが良いか悪いと言うことはできません。私の思うあなたの必要に応じて。私の答えはキャッシングなしではほとんど確実に遅くなります。 私がこのソリューションに関して特に気に入っている点は、エミュレートしようとしている組み込みの言語機能を使用していることです。それをシミュレートするのではなく、 – jonfuller