首页 文章

为什么C#构造函数不能推断类型?

提问于
浏览
145

为什么构造函数不支持类型推断,就像通用方法一样?

public class MyType<T>
{
   private readonly T field;
   public MyType(T value) { field = value; }
}

var obj = new MyType(42); // why can't type inference work out that I want a MyType<int>?

虽然你可以用工厂类解决这个问题,

public class MyTypeFactory
{
   public static MyType<T> Create<T>(T value)
   {
      return new MyType<T>(value);
   }
}
var myObj = MyTypeFactory.Create(42);

构造函数不支持类型推断是否存在实际或哲学原因?

5 回答

  • 0

    构造函数不支持类型推断是否存在哲学原因?

    没有 . 当你有

    new Foo(bar)
    

    然后我们可以在范围内识别所有称为Foo的类型,而不管通用arity,然后使用修改的方法类型推断算法对每个类型进行重载解析 . 我们'd then have to create a ' betterness'算法确定两种类型中具有相同名称但不同通用arity的两个适用构造函数中的哪一个是更好的构造函数 . 为了保持向后兼容性,非泛型类型的ctor必须始终获胜 .

    构造函数不支持类型推断是否有实际原因?

    是 . 即使该功能的好处超过其成本 - 这是相当大的 - 但这还不足以实现功能 . 这个功能不仅必须是一个净赢,它必须是一个巨大的净胜利相比我们可能投资的所有其他可能的功能 . 它还必须比花费时间和精力修复bug,性能更好工作,以及我们可以付出努力的其他可能领域 . 理想情况下,它必须适合发布的"theme" .

    此外,正如您正确指出的那样,通过使用工厂模式,您可以获得此功能的好处,而无需实际拥有该功能 . 易于使用的变通方法使得功能实现的可能性降低 .

    此功能长期以来一直列在可能的功能列表中 . 它实际上从未在列表中足够高的地方实现 .

    更新2015年3月

    建议的功能使其足够接近C#6列表顶部的指定和设计,但随后被剪切 .

  • 17
    public class MyType<T> 
    { 
       private readonly T field; 
       public MyType(T value) { field = value; } 
    }
    

    他们可以,没有必要再次告诉构造函数“T是什么”,因为你已经在课堂上已经完成了这一点 .

    您的工厂也不正确,您需要 public class MyTypeFactory<T> 而不仅仅是 public class MyTypeFactory - 除非您在 MyType 类中声明工厂

    编辑更新:

    那么,42是长,短,是int还是其他什么?

    假设您有以下内容

    class Base
    {
       public virtual void DoStuff() { Console.WriteLine("Base"); }
    }
    
    class Foo : Base
    {
       public override void DoStuff() { Console.WriteLine("Foo");  }
    }
    

    然后你做到了这一点

    var c = new Foo();
    
    var myType = new MyType(c);
    

    你期望使用 foo ,还是 base ?我们需要告诉编译器使用什么代替 T

    当你真的想上类型 base

    因此

    var myType = new MyType<Base>(c);
    
  • 11

    泛型类型推断不能像你希望的那样对构造函数起作用的主要原因是因为当你声明的所有类都是“MyType <T>”时,类“MyType”甚至不存在 . 请记住,同时拥有两者是合法的:

    public class MyType<T> {
    }
    

    and

    public class MyType {
    }
    

    两者都是合法的 . 如果您确实声明了两者,并且它们都声明了冲突的构造函数,那么您将如何消除语法歧义?

  • 1

    构造函数需要与类本身具有相同的通用规范 . 否则,将无法知道示例中的 int 是否与类或构造函数相关 .

    var obj = new MyType<int>(42);
    

    那是带有构造函数 MyType(int) 的类 MyType<T> 还是带有构造函数 MyType<T>(T) 的类 MyType

  • 114

    虽然之前已经多次回答过,但我觉得我需要澄清一件事:C#支持构造函数的泛型类型推断 . 问题是,它既不支持向构造函数添加泛型参数也不支持类型泛型类型推断 . 想要推断类型本身的泛型类型参数与要求 Foo.Bar(0) 推断为 Foo<int>.Bar(0) 基本相同 .

相关问题