[英]Why can't the C# constructor infer type?
为什么构造函数不支持泛型方法的类型推断?
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);
构造函数不能支持类型推断是否有实际或哲学上的原因?
构造函数不能支持类型推断有哲学上的原因吗?
不,当你有
new Foo(bar)
然后我们可以在范围内识别所有称为 Foo 的类型,而不管泛型数量如何,然后使用修改的方法类型推断算法对每个类型进行重载解析。 然后,我们必须创建一个“更好”算法,以确定具有相同名称但具有不同泛型的两种类型中的两个适用构造函数中的哪一个是更好的构造函数。 为了保持向后兼容性,非泛型类型的 ctor 必须始终获胜。
构造函数不能支持类型推断有实际原因吗?
是的。 即使该功能的好处超过其成本——这是相当大的——也不足以实现一个功能。 与我们可以投资的所有其他可能的功能相比,该功能不仅必须是净赢,而且必须是巨大的净赢。它还必须比花费时间和精力在错误修复、性能上更好工作,以及我们可以投入的其他可能领域。 理想情况下,它必须很好地适应发行版的“主题”。
此外,正如您正确指出的那样,您可以通过使用工厂模式获得此功能的好处,而无需实际拥有该功能本身。 简单的变通方法的存在降低了实现某个功能的可能性。
很长一段时间以来,此功能一直在可能的功能列表中。 它在列表中的位置从来没有足够高以至于无法实际实施。
提议的功能使它足够接近 C# 6 的列表顶部,以便指定和设计,但随后被删除。
public class MyType<T>
{
private readonly T field;
public MyType(T value) { field = value; }
}
他们可以,没有必要再次告诉构造函数“T 是什么”,因为您已经在类声明中这样做了。
您的工厂也不正确,您需要拥有public class MyTypeFactory<T>
而不仅仅是public class MyTypeFactory
- 除非您在MyType
类中声明工厂
编辑更新:
那么,42 是 long、short、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);
泛型类型推断不能像您希望的那样在构造函数上起作用的主要原因是,当您声明的所有内容都是“MyType<T>”时,“MyType”类甚至都不存在。 请记住,两者兼有是合法的:
public class MyType<T> {
}
和
public class MyType {
}
两者都是合法的。 如果您确实声明了两者,并且它们都声明了一个冲突的构造函数,那么您将如何消除语法歧义。
构造函数需要与类本身具有相同的通用规范。 否则,将无法知道示例中的int
是否与类或构造函数相关。
var obj = new MyType<int>(42);
那是带有构造函数 MyType<T MyType<T>
的类MyType
MyType(int)
还是带有构造函数MyType<T>(T)
的类 MyType ?
虽然这个问题之前已经回答过很多次了,但我觉得我需要澄清一件事:C#支持构造函数的泛型类型推断。 问题是,它既不支持向构造函数添加泛型参数也不支持类型泛型类型推断。 想要推断类型本身的泛型类型参数与要求Foo.Bar(0)
推断Foo<int>.Bar(0)
基本相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.