Can someone explain how the compiler proceeds here to find the "common" type (double).
I assume the IConvertible plays a role here?
private static void Main(string[] args)
{
var nrColl = new[] { 1, 2, 0.14, 'a',};
}
Can someone explain how the compiler proceeds here to find the "common" type (double).
I assume the IConvertible plays a role here?
private static void Main(string[] args)
{
var nrColl = new[] { 1, 2, 0.14, 'a',};
}
This happens because every type you give it here is implicitly convertable to a double.
When you try to change the char ('a'
) to a string ("a"
) you'll notice that it won't work anymore. This is because a character in .Net is nothing more than a UInt16 with some additional methods and different Overrides (for example ToString
) and it defines a implicit conversion to double.
Here is a example:
public static void Main()
{
var bar = new[] { 1, 2, 0.14, 'a', new Foo(42)};
}
public class Foo
{
public Foo(int value)
{
_value = value;
}
private int _value;
public static implicit operator double(Foo foo)
{
return foo._value;
}
}
Interestingly this also works if no direct implicit operator exists, but a chain of multiple implicit operators exists.
public static void Main()
{
var bar = new[] { 1, 2, 0.14, 'a', new Foo(42)};
}
public class Foo
{
public Foo(int value)
{
_value = value;
}
private int _value;
public static implicit operator int(Foo foo)
{
return foo._value;
}
}
But this 'conversion chaining' only seems to work with internal types for some reason.
This doesn't work:
public static void Main()
{
var bar = new[] { 1, 2, 0.14, 'a', new Foo(42)};
}
public class Bar
{
public Bar(int value)
{
Value = value;
}
public int Value { get; set; }
public static implicit operator double(Bar bar) => bar.Value;
}
public class Foo
{
public Foo(int value)
{
_value = value;
}
private int _value;
public static implicit operator Bar(Foo foo)
{
return new Bar(foo._value);
}
}
See Finding the best common type of a set of expressions in the specification.
If you follow the steps of how an output type inference is done, you will eventually see that in this case the type variable
X
will have the lower boundsint
,double
, andchar
.Then, to fix
X
,We can try to do that manually.
Let's first examine
int
.int
can be implicitly converted todouble
, sodouble
is not removed.int
cannot be converted tochar
, sochar
is removed. Next we will examinedouble
.double
cannot be implicitly converted toint
, soint
is removed. We are now only left withdouble
, and soX
is fixed todouble
.Basically, if there is exactly one type
T
in the types of the expressions in the array initialiser, that all the other expressions can be implicitly converted to, thenT
is the type of the array.