2011-11-15 10 views
14

Esempio 1 (non compila):In che modo Lazy <T> ha bisogno di un nuovo() vincolo?

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

Risultato:

Impossibile creare un'istanza del tipo di variabile 'T', perché non ha il nuovo() vincolo

Esempio 2 (opere):

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 

risposta

17

Se approfondire il codice sorgente, vedrete che in ultima analisi, Lazy<T> utilizza Activator:

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

Questa è solo una scorciatoia per l'utilizzo di riflessione. Poiché non sta creando un'istanza del tipo tramite l'effettivo argomento di tipo generico (new T()) ma piuttosto invocando il costruttore tramite il reflection, non è necessario il vincolo where T : new().

Problemi correlati