简体   繁体   中英

Type inference in C# not working?

Given the following C# code:

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

And its counterpart in 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:

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

Is there a way to auto-infer type in C# for the above scenario?

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 ). 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. 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. 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:

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.

Best Practices: Option Infer

In C# you could use dynamic : dynamic[] k = { "1", 2, "3" };

It doesn't mimic VB's behaviour completey, though. dynamic[] k = { "1", "2", "3" }; still gives you an array of object, while in VB you get an array of 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 ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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