Why is an explicit conversion from double
to Foo
possible, even though Foo
only defined an explicit conversion from int
to Foo
?
Why is in my case double
implicitly converted to an int
?
using System;
class Program
{
static void Main(string[] args)
{
double doub = 15.7;
Foo foo = (Foo)doub;
Console.WriteLine(foo.value); //writes "15"
}
}
struct Foo
{
public int value;
public static explicit operator Foo(int val) //no matter if implicit
{
return new Foo { value = val };
}
}
I believe this is layed out in section 6.4.3 of the C# 5 Language Specification.
A first hint is given in section 6.2.8 User Defined explicit conversions (emphasis mine):
A user-defined explicit conversion consists of an optional standard explicit conversion, followed by execution of a user-defined implicit or explicit conversion operator, followed by another optional standard explicit conversion
Notice how not one but potentially three conversions occur.
Now, to know what is a 'standard explicit conversion' we have to look at section 6.2.3 Standard explicit conversions
:
The standard explicit conversions are all standard implicit conversions plus the subset of the explicit conversions for which an opposite standard implicit conversion exists. In other words, if a standard implicit conversion exists from a type A to a type B, then a standard explicit conversion exists from type A to type B and from type B to type A.
And looking back at section 6.3.1 Standard implicit conversions
we can see that this is a part of it:
- Implicit numeric conversions (§6.1.2)
In other words: an explicit numeric conversion (like double -> int
) can be applied before the user-defined conversion.
If we now look at 6.4.3 Evaluation of user-defined conversions
we see the following (emphasis mine):
First, if required, performing a standard conversion from the source type to the operand type of the userdefined or lifted conversion operator
Next, invoking the user-defined or lifted conversion operator to perform the conversion.
Finally, if required, performing a standard conversion from the result type of the user-defined or lifted conversion operator to the target type.
Which is exactly what happens in your scenario.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With