2011-03-03 13 views
12

Bu soruya cevap verebilecek insanlar olduğunu düşünüyorum, bu meraktan bir sorudur:Gerçekten önemli olandan çok daha fazla trivia: Neden Activator.CreateInstance <T>() üzerinde yeni() kısıtlaması yok?

.NET v2'de tanıtılan System.Activator'dan alınan jenerik CreateInstance yöntemi, genel argüman üzerinde hiçbir tür kısıtlamaya sahip değildir ancak Etkinleştirilmiş türde varsayılan kurucu, aksi takdirde bir MissingMethodException atılır. Bana göre, bu yöntemin

Activator.CreateInstance<T>() where T : new() { 
    ... 
} 

gibi bir tür kısıtlaması olması gerektiği açıktır. Sadece bir ihmal mi yoksa burada gizlenen bir anektod mu?

Belirtildiği gibi, derleyici

private T Create<T>() where T : struct, new() 
error CS0451: The 'new()' constraint cannot be used with the 'struct' constraint 

yazmanıza izin vermez Ancak, bkz. struct (yeni) belirten jenerik bir yönteme type argümanı olarak bir struct kullanılabilir.) kısıtlama. Bu durumda verilen cevap, yöntemin sınırlandırılmaması için tek geçerli neden gibi görünüyor ...

Bunu incelediğiniz için teşekkürler!

+0

+1 Çok ilginç bir soru. Orada olmamasının nedenini düşünemiyorum, bu yüzden nedenini de merak ediyorum! –

+0

Güncellemeniz hakkında, çünkü gereksizdir; tüm değer türlerinin varsayılan değerlerini varsayılanlara atanan varsayılan bir kurucu vardır (varsayılan (T) 'yi çağırdığınızda aldığınız şey budur. –

+0

Tüm yapıların C# varsayılan değerlerini içerir. – Linkgoron

cevap

7

Yanılıyor olabilirim, ama ana parası ben seni böyle bir şey yapmak izin vermesidir gördüğünüz gibi:

// Simple illustration only, not claiming this is awesome code! 
class Cache<T> 
{ 
    private T _instance; 

    public T Get() 
    { 
     if (_instance == null) 
     { 
      _instance = Create(); 
     } 

     return _instance; 
    } 

    protected virtual T Create() 
    { 
     return Activator.CreateInstance<T>(); 
    } 
} 

Not Activator.CreateInstance<T> sonra where T : new() kısıtlamayı olsaydı Cache<T> sınıf yukarıda olur o da, Create sanal bir yöntem olduğundan ve türetilmiş bir sınıfın türün dahili yapıcısını çağırmak veya bir statik oluşturucu yöntemi kullanmak gibi farklı bir örnekleme aracı kullanmak isteyebileceğinden aşırı kısıtlayıcı olan bu kısıtlamaya gereksinim duyar.

+0

+1.Bu mükemmel bir nokta. T 'burada kesinlikle bir varsayılan kurucu yok,), bu kesinlikle geçerli bir durum gibi görünüyor. –

+0

Evet, mantıklı geliyor – flq

+0

Tesadüfen, 'Sy gibi görünüyor stem.Runtime.CompilerServices.ConditionalWeakTable' bunu yapar. –

İlgili konular