为什么C#不接受带有泛型参数的构造函数要求?

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语言.什么是证明该功能合理的令人信服的好处?

而且:假设我们设计了这个功能.如何有效实施?在通用类型的系统的约束已被仔细地设计,使得抖动能产生高效的代码一次,然后可以为每一个参考类型共享.我们如何为任意方法模式匹配生成有效的代码?当在编译时知道方法的槽时,那种有效的分派非常简单; 有了这个功能,我们将不再具有这种优势.

您想要的功能是相同的功能,只是限制在构造函数的方法.

请记住,泛型的目的是让您编写通用类型的代码.如果您需要的约束比类型系统中可以捕获的内容更具体,那么您可能会尝试滥用泛型.

  • @Ariel:你的问题的答案是直截了当的:**这个小得多的特征的成本是由它带来的好处**证明的. (2认同)
  • @Michael:那就是那个问题.接口适用于一般问题---构造函数的_except_.您不能将.ctor放入接口. (2认同)
  • 为了回答有关如何有效实现它的问题,一种方法(由F#采用,允许这样的约束)是在每个调用站点内联特定于类型的代码版本,从而失去共享的好处. (2认同)

Jam*_*iec 7

而不是试图猜测微软为什么决定某个特定的实现,这里有一个使用工厂模式的解决方法

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)