2011-11-15 6 views
14

例1(コンパイルされません):Lazy <T>はどのようにnew()制約が必要ですか?

void Main() 
{ 
    var c = new C<D>(); 
    c.M.F(); 
} 

class C<T> 
{ 
    T _m = null; 
    public T M { get { 
     if(_m == null) _m = new T(); 
     return _m; 
    } } 
} 

class D 
{ 
    public void F() { Console.WriteLine ("i was created"); } 
} 

結果:

それは新しい()制約

を持っていないので、変数の型 'T' のインスタンスを作成できません

例2(作品):

void Main() 
{ 
    var c = new C<D>(); 
    c.M.F(); 
} 

class C<T> 
{ 
    Lazy<T> _m = new Lazy<T>(); 
    public T M { get { return _m.Value; } } 
} 

class D 
{ 
    public void F() { Console.WriteLine ("i was created"); } 
} 

Resul T:あなたがソースコードを詳細に調べる場合

i was created 

答えて

17

、あなたはLazy<T>が最終的にActivatorを使用していることがわかります:

return new Lazy<T>.Boxed((T)Activator.CreateInstance(typeof(T))); 

これは、リフレクションを使用するための単なるショートカットです。実際のジェネリック型引数(new T())でタイプをインスタンス化するのではなく、リフレクションによってコンストラクタを呼び出すため、where T : new()の制約は必要ありません。