Aşağıda gösterilen örnek kodda, "CompileError" yöntemi derlenmeyecektir, çünkü CreateWithNew()
yönteminde gösterildiği gibi where T : new()
kısıtlaması gerektirir. Bununla birlikte, CreateWithActivator<T>()
yöntemi, bir kısıtlama olmaksızın yalnızca iyi derler.Neden activator.CreateInstance <T>() yeni() jenerik tür kısıtlaması olmadan izin verilir?
public class GenericTests
{
public T CompileError<T>() // compile error CS0304
{
return new T();
}
public T CreateWithNew<T>() where T : new() // builds ok
{
return new T();
}
public T CreateWithActivator<T>() // builds ok
{
return Activator.CreateInstance<T>();
}
}
Neden?
MSDN documentation başvuran https://stackoverflow.com/a/1649108/531971 göreve this question, jenerik new T()
sentezleme aslında Activator.CreateInstance<T>()
kullanılarak uygulamıştır. Bu yüzden, neden new T()
numaralı telefonun aranmasının, jenerik türün Activator.CreateInstance<T>()
kullanıldığında atlanabilecek şekilde kısıtlanmasını gerektirdiğini anlamıyorum.
Veya tersi soru koymak; doğrudan tam aynı temel altyapısını kullanarak, kısıtlama olmaksızın genel bir yöntemde T
örneklerini oluşturmak kolaydır eğer where T : new()
kısıtlama noktası ne?
Çünkü CreateInstance() 'sadece düz eski yansımayı kullanır ve herhangi bir kısıtlamaya tabi değildir. Türün varsayılan kurucusu varsa, bunu oluşturacaktır. –
Bu, kendi kendini kontrol eden bir şeydir. Yansıma yoluyla her şeyi yapabilirsiniz (tüm OOP prensiplerini bile yok edin), fakat çoğu bunu takdir etmez, kirlenmesine neden olur. – eocron
Bir derleme zamanı hatasını ortadan kaldırmanıza ve bunun yerine çalışma zamanı oluşturmanıza olanak tanıyan garip kod yazmanın birçok yolu vardır. Bu sadece bir örnek. Örneğin. '' dinamik', mevcut olmayan fonksiyonlara çağrı yazmanıza izin verir, bu yüzden derleyici hatası yerine çalışma zamanı istisnası alırsınız. Aynı şekilde, burada, "CreateInstance", çalışma zamanına kadar parametresiz bir kurucunun bulunmadığını öğrenmeyi ertelemenize izin verir. –