I’m just replying to the first part of the question to start with. (I suggest that the second part should be a separate question; it’s more likely to be a bug.)
There’s only an explicit conversion from decimal to int, but that conversion is being implicitly called in your code. The conversion happens in this IL:
IL_0010: stloc.0
IL_0011: ldloc.0
IL_0012: call int32 [mscorlib]System.Decimal::op_Explicit(valuetype [mscorlib]System.Decimal)
IL_0017: call valuetype NumberFixedPoint2 NumberFixedPoint2::op_Implicit(int32)
I believe this is the correct behaviour according to the spec, even though it’s surprising1. Let’s work our way through section 6.4.5 of the C# 4 spec (User-Defined Explicit Conversions). I’m not going to copy out all the text, as it would be tedious – just what the relevant results are in our case. Likewise I’m not going to use subscripts, as they don’t work well with code font here 🙂
- Determine the types
S0andT0:S0isdecimal, andT0isNumberFixedPoint2. - Find the set of types,
D, from which used-defined conversion operators will be considered: just{ decimal, NumberFixedPoint2 } - Find the set of applicable user-defined and lifted conversion operators,
U.decimalencompassesint(section 6.4.3) because there’s a standard implicit conversion frominttodecimal. So the explicit conversion operator is inU, and is indeed the only member ofU - Find the most specific source type,
Sx, of the operators inU- The operator doesn’t convert from
S(decimal) so the first bullet is out - The operator doesn’t convert from a type that encompasses
S(decimalencompassesint, not the other way round) so the second bullet is out - That just leaves the third bullet, which talks about the “most encompassing type” – well, we’ve only got one type, so that’s okay:
Sxisint.
- The operator doesn’t convert from
- Find the most specific target type,
Tx, of the operators inU- The operator convers straight to
NumberFixedPoint2soTxisNumberFixedPoint2.
- The operator convers straight to
- Find the most specific conversion operator:
Ucontains exactly one operator, which does indeed convert fromSxtoTx, so that’s the most specific operator
- Finally, apply the conversion:
- If
Sis notSx, then a standard explicit conversion fromStoSxis performed. (So that’sdecimaltoint.) - The most specific user-defined conversion operator is invoked (your operator)
TisTxso there’s no need for the conversion in the third bullet
- If
The line in bold is the bit which confirms that a standard explicit conversion really is feasible, when only an explicit conversion from a different type is actually specified.
1 Well I found it surprising, at least. I’m not aware of seeing this before.