Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Compiler cannot infer the object array type?

I am wondering why this is valid :

object[] array = {"bla bla bla..", 23, true};

But these are not:

var array = {"bla bla bla..", 23, true };
var array2 = new [] {"bla bla bla..", 23, true };

In the second example why compiler cannot infer the array type according to values in the array initializer? It seems really easy to do, especially as compared to generic type inference.In order to define an object array why do I have to specify the array type explicitly ?

var array = new object[] { "bla bla bla..", 23, true };
like image 789
Selman Genç Avatar asked Jan 10 '23 23:01

Selman Genç


2 Answers

Because the types in the array aren't specific object - they are 3 different types that are all subclasses of object.

If you use a specific type that can be inferred in your array, the compiler will infer the type. For example, this is fine:

var arr = new[] {3, 4, 5}; // Will correctly infer int[]

Note that this is explicitly called out in 8.5.1 of the C# language spec, which states that for var is subject to the following restrictions:

  • The local-variable-declaration cannot include multiple local-variable-declarators.
  • The local-variable-declarator must include a local-variable-initializer.
  • The local-variable-initializer must be an expression.
  • The initializer expression must have a compile-time type.
  • The initializer expression cannot refer to the declared variable itself

In the case of arrays, there is an example specified:

var y = {1, 2, 3};   // Error, array initializer not permitted

As for the new [] {"bla bla bla..", 23, true }; example, this is called out in 7.6.10. There, this example:

var d = new[] { 1, "one", 2, "two" }; // Error

Is said to be an error because:

The last expression causes a compile-time error because neither int nor string is implicitly convertible to the other, and so there is no best common type. An explicitly typed array creation expression must be used in this case, for example specifying the type to be object[]. Alternatively, one of the elements can be cast to a common base type, which would then become the inferred element type

like image 78
Reed Copsey Avatar answered Jan 19 '23 03:01

Reed Copsey


I would say it's more of a safety feature. Sure, the compiler could always infer the least-common denominator, object.

But consider the consequences: You make a mistake when initializing an array that you intended to be of a specific type: (here int)

var array = {1, 2, 3, 4, 5, "6", 7, 8, 9};

Through a copy & paste error, you leave "6" as a string. Instead of throwing a compiler error, you're left with an unintended object[], which could cause problems down the road where you were intending int[].

This isn't Python - I prefer to have explicit typing over a savings of a few characters.

like image 44
Jonathon Reinhart Avatar answered Jan 19 '23 04:01

Jonathon Reinhart