[英]Why C# don't accept constructor requirements with parameters on generics?
與 C# Generics 一起使用,您可以擁有這樣的 class:
class Foo<T> where T:new() {}
這意味着類型 T 應該有一個沒有參數的構造函數。 如果我們能有,那就太好了:
class Foo<T> where T : new(string)
{
private T CreateItem()
{
string s="";
return new T(s);
}
}
微軟沒有將此功能添加到語言中是否有任何原因?
微軟沒有將此功能添加到語言中是否有任何原因?
您描述的功能是更通用功能“允許需要特定方法存在的約束”的特定情況。 例如,你可能會說:
void M<T>(T t) where T has an accessible method with signature double Foo(int)
{
double x = t.Foo(123);
}
我們在 C# 中沒有該功能,因為必須通過成本效益分析來證明這些功能是合理的。 從設計和實現的角度來看,這將是一個相當昂貴的特性——這個特性不僅會推動對 C# 的需求,還會對每一種 .NET 語言提出需求。 證明該功能合理的引人注目的好處是什么?
此外:假設我們確實設計了該功能。 它將如何有效地實施? 泛型類型系統中的約束經過精心設計,因此抖動可以生成有效的代碼,然后可以為每個引用類型共享。 我們如何為任意方法模式匹配生成有效的代碼? 當方法的槽可以在編譯時知道時,這種高效的分派非常簡單。 有了這個功能,我們將不再有這個優勢。
您想要的功能是相同的功能,只是方法類型僅限於構造函數。
請記住,generics 的目的是讓您編寫通用類型的代碼。 如果您需要的約束比可以在類型系統中捕獲的內容更具體,那么您可能會嘗試濫用 generics。
與其嘗試猜測 Microsoft 決定采用特定實現的原因,不如使用工廠模式為您提供一種解決方法
public interface IFactory<T>
{
T CreateItem(string s);
}
class Foo<TFactory,T> where TFactory : IFactory<T>, new()
{
private T CreateItem()
{
var factory = new TFactory();
string s="";
return factory.CreateItem(s);
}
}
使用這種模式,假設你有一個 class Bar
,它的構造函數采用單個字符串:
public class Bar
{
public Bar(string laa)
{}
}
您只需要一個實現IFactory<Bar>
的BarFactory
public class BarFactory : IFactory<Bar>
{
public BarFactory () {}
public Bar CreateItem(string s)
{
return new Bar(s);
}
}
現在你可以用 Foo 使用那個工廠了
var foo = new Foo<BarFactory,Bar>(); // calls to CreateItem() will construct a Bar
當我想要一個使用 arguments 調用構造函數的通用 function 時,我采用的解決方案是使用反射來查找和調用它。
鑒於我控制了泛型以及實現它的所有類(並且這個 function 是構造這些類的唯一地方),我想我可能會更好地給這些類一個默認構造函數並添加一個 Initialize他們都實現的接口中的方法。
(通常允許將 static 方法添加到接口的解決方案是理想的。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.