Ari*_*iel 2 c# generics constructor
使用C#Generics,您可以拥有这样的类:
class Foo<T> where T:new() {}
Run Code Online (Sandbox Code Playgroud)
这意味着类型T应该有一个没有参数的构造函数.如果我们能够:
class Foo<T> where T : new(string)
{
private T CreateItem()
{
string s="";
return new T(s);
}
}
Run Code Online (Sandbox Code Playgroud)
是否有任何理由说微软没有在该语言中添加此功能?
Eri*_*ert 10
是否有任何理由说微软没有在该语言中添加此功能?
您描述的功能是更一般的功能"允许需要特定方法存在的约束"的特定情况.例如,您可能会说:
void M<T>(T t) where T has an accessible method with signature double Foo(int)
{
double x = t.Foo(123);
}
Run Code Online (Sandbox Code Playgroud)
我们在C#中没有这个功能,因为功能必须通过成本效益分析来证明.从设计和实现的角度来看,这将是一个非常昂贵的功能 - 这个功能可以将需求推向不仅仅是C#而是每个.NET语言.什么是证明该功能合理的令人信服的好处?
而且:假设我们设计了这个功能.如何有效实施?在通用类型的系统的约束已被仔细地设计,使得抖动能产生高效的代码一次,然后可以为每一个参考类型共享.我们如何为任意方法模式匹配生成有效的代码?当在编译时知道方法的槽时,那种有效的分派非常简单; 有了这个功能,我们将不再具有这种优势.
您想要的功能是相同的功能,只是限制在构造函数的方法.
请记住,泛型的目的是让您编写通用类型的代码.如果您需要的约束比类型系统中可以捕获的内容更具体,那么您可能会尝试滥用泛型.
而不是试图猜测微软为什么决定某个特定的实现,这里有一个使用工厂模式的解决方法
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);
}
}
Run Code Online (Sandbox Code Playgroud)
使用这种模式,假设你有一个类Bar,它有一个构造函数采用单个字符串:
public class Bar
{
public Bar(string laa)
{}
}
Run Code Online (Sandbox Code Playgroud)
你只需要一个BarFactory实现IFactory<Bar>
public class BarFactory : IFactory<Bar>
{
public BarFactory () {}
public Bar CreateItem(string s)
{
return new Bar(s);
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以将该工厂与Foo一起使用
var foo = new Foo<BarFactory,Bar>(); // calls to CreateItem() will construct a Bar
Run Code Online (Sandbox Code Playgroud)