简体   繁体   English

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

[英]Type inference in C# not working?

Given the following C# code: 给出以下C#代码:

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

And its counterpart in VB.NET: 与VB.NET中的对应物:

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

It appears that VB.NET is able to correctly infer type of a = Object() , while C# complains until the above is fixed to: 似乎VB.NET能够正确地推断a = Object() ,而C#会抱怨,直到上面的内容被修复为:

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

Is there a way to auto-infer type in C# for the above scenario? 有没有办法在上述场景中自动推断C#中的类型?

EDIT: Interesting observation after playing with different types in a C# sandbox - type is correctly inferred if all elements have common parent in the inheritance tree, and that parent is not an Object , or if elements can be cast into a wider type (without loss of precision, for example Integer -> Double ). 编辑:在C#沙箱中使用不同类型后的有趣观察 - 如果所有元素在继承树中具有共同父项,并且该父项不是 Object ,或者如果元素可以转换为更宽泛的类型(无损失),则可以正确推断类型精度,例如Integer -> Double )。 So both of these would work: 所以这两个都可行:

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

I think this behavior is inconsistent in C#, because all types inherit from Object , so it's not a much different ancestor than any other type. 我认为这种行为在C#中是不一致的,因为所有类型都继承自Object ,所以它与其他任何类型的祖先都没有太大不同。 This is probably a by-design, so no point to argue, but if you know the reason, would be interesting to know why. 这可能是一个设计,所以没有必要争论,但如果你知道原因,知道原因会很有趣。

No. Implicitly typed arrays in C# require that the type of one of the expressions in the array initializer is of the target type. 否.C#中的隐式类型数组要求数组初始值设定项中某个表达式的类型是目标类型。 Basically, the compiler tries to find exactly one element type such that all the other types can be converted to it. 基本上,编译器试图找到恰好一个元素类型,以便可以将所有其他类型转换为它。

You could cast any of the elements to object of course: 您当然可以将任何元素转换为object

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

... but then you might as well just use an explicitly typed array initializer: ...但是你可能只使用一个显式类型的数组初始值设定项:

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

Or in cases where you really are declaring a variable at the same time: 或者在您确实同时声明变量的情况下:

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

No. However, you can make VB behave more like C# by using Option Explicit On, Option Strict On, and Option Infer Off. 不可以。但是,通过使用Option Explicit On,Option Strict On和Option Infer Off,可以使VB更像C#。

Best Practices: Option Infer 最佳实践:选项推断

In C# you could use dynamic : dynamic[] k = { "1", 2, "3" }; 在C#中你可以使用dynamicdynamic[] k = { "1", 2, "3" };

It doesn't mimic VB's behaviour completey, though. 但它并不完全模仿VB的行为。 dynamic[] k = { "1", "2", "3" }; still gives you an array of object, while in VB you get an array of String. 仍然给你一个对象数组,而在VB中你得到一个String数组。

And of course: 而且当然:

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

compiles without problem, but most likely will fail miserably ;) 编译没有问题,但很可能会悲惨地失败;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM