Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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.)</p> <p>There's only an <em>explicit</em> conversion from <code>decimal</code> to <code>int</code>, but that conversion is being <em>implicitly</em> called in your code. The conversion happens in this IL:</p> <pre><code>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) </code></pre> <p>I believe this is the <em>correct</em> behaviour according to the spec, even though it's surprising<sup>1</sup>. 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 :)</p> <ul> <li>Determine the types <code>S0</code> and <code>T0</code>: <code>S0</code> is <code>decimal</code>, and <code>T0</code> is <code>NumberFixedPoint2</code>.</li> <li>Find the set of types, <code>D</code>, from which used-defined conversion operators will be considered: just <code>{ decimal, NumberFixedPoint2 }</code></li> <li>Find the set of applicable user-defined and lifted conversion operators, <code>U</code>. <code>decimal</code> <em>encompasses</em> <code>int</code> (section 6.4.3) because there's a standard implicit conversion from <code>int</code> to <code>decimal</code>. So the explicit conversion operator <em>is</em> in <code>U</code>, and is indeed the only member of <code>U</code></li> <li>Find the most specific source type, <code>Sx</code>, of the operators in <code>U</code> <ul> <li>The operator doesn't convert from <code>S</code> (<code>decimal</code>) so the first bullet is out</li> <li>The operator doesn't convert from a type that encompasses <code>S</code> (<code>decimal</code> encompasses <code>int</code>, not the other way round) so the second bullet is out</li> <li>That just leaves the third bullet, which talks about the "most encompassing type" - well, we've only got one type, so that's okay: <code>Sx</code> is <code>int</code>.</li> </ul></li> <li>Find the most specific target type, <code>Tx</code>, of the operators in <code>U</code> <ul> <li>The operator convers straight to <code>NumberFixedPoint2</code> so <code>Tx</code> is <code>NumberFixedPoint2</code>.</li> </ul></li> <li>Find the most specific conversion operator: <ul> <li><code>U</code> contains exactly one operator, which does indeed convert from <code>Sx</code> to <code>Tx</code>, so that's the most specific operator</li> </ul></li> <li>Finally, apply the conversion: <ul> <li><strong>If <code>S</code> is not <code>Sx</code>, then a standard explicit conversion from <code>S</code> to <code>Sx</code> is performed.</strong> (So that's <code>decimal</code> to <code>int</code>.)</li> <li>The most specific user-defined conversion operator is invoked (your operator)</li> <li><code>T</code> is <code>Tx</code> so there's no need for the conversion in the third bullet</li> </ul></li> </ul> <p>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.</p> <hr> <p><sup>1</sup> Well I found it surprising, at least. I'm not aware of seeing this before.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload