C#中的类型推断不起作用?

时间:2012-11-20 22:41:56

标签: c# vb.net type-inference

给出以下C#代码:

var a = new[] {"123", "321", 1}; //no best type found for implicitly typed array

与VB.NET中的对应物:

Dim a = {"123", "321", 1} 'no errors

似乎VB.NET能够正确推断出a = Object()的类型,而C#会一直抱怨,直到上面的内容被修复为:

var a = new object[] {"123", "321", 1};

对于上述场景,有没有办法在C#中自动推断类型?

编辑:在C#沙箱中使用不同类型后的有趣观察 - 如果所有元素在继承树中都有公共父级,并且该父级不是 Object,或者可以将元素强制转换为更宽的类型(不会丢失精度,例如Integer -> Double)。所以这两个都可行:

var a = new[] {1, 1.0}; //will infer double[]
var a = new[] {new A(), new B()}; //will infer A[], if B inherits from A

我认为这种行为在C#中是不一致的,因为所有类型都继承自Object,所以它与其他任何类型的祖先都没有太大不同。这可能是一个副设计,所以没有必要争论,但如果你知道原因,知道原因会很有趣。

3 个答案:

答案 0 :(得分:9)

没有。 C#中的隐式类型数组要求数组初始值设定项中表达式的 one 的类型是目标类型。基本上,编译器试图找到恰好一个元素类型,以便可以将所有其他类型转换为它。

您当然可以将任何元素投射到object

var a = new[] { (object) "123", "321", 1}; 

...但是你可能只使用一个明确类型化的数组初始值设定项:

var a = new object[] {"123", "321", 1}; 

或者你真的 同时声明变量的情况:

object[] a = {"123", "321", 1};

答案 1 :(得分:2)

没有。但是,通过使用Option Explicit On,Option Strict On和Option Infer Off,可以使VB更像C#。

Best Practices: Option Infer

答案 2 :(得分:1)

在C#中,您可以使用dynamicdynamic[] k = { "1", 2, "3" };

但是,它并没有完全模仿VB的行为。 dynamic[] k = { "1", "2", "3" }; 仍然给你一个对象数组,而在VB中你得到一个String数组。

当然:

dynamic[] k = { "1", "3", "3" };
int i = k[0].I_do_not_exist();

编译没有问题,但很可能会悲惨地失败;)