Code:
void Main()
{
C.F();
}
public class C
{
public static void F()
{
var a = new A { i = 1, d = 2.5m };
var b = new B(a);
I(b);
D(b);
}
static void I(int i) { Console.WriteLine("int is: " + i); }
static void D(decimal d) { Console.WriteLine("decimal is: " + d); }
}
public class A
{
public int i;
public decimal d;
}
public class B
{
A _a;
public B(A a) { _a = a; }
public static implicit operator int(B b) { return b._a.i; }
public static implicit operator decimal(B b) { return b._a.d; }
}
OUTPUT:
int is: 1
decimal is: 2.5
Comment out:
//public static implicit operator decimal(B b) { return b._a.d; }
OUTPUT:
int is: 1
decimal is: 1
What is going on when the second version runs and outputs 1 for both cases?
My guess is that the compiler sees that there is an implicit conversion from
Btoint, and an implicit (built-in) conversion frominttodecimal, so that it can use both in sequence. In other words, the call becomesD((decimal)(int)b).Note that nothing is being truncated; rather, an
intis being promoted to adecimal. If instead you comment out theintconversion, I expect thatI(b)will fail, since even though there is an implicit cast fromBtodecimal, there is no implicit cast fromdecimaltoint.