Multiple explicit system converters are allowed, but explicit converters with multiple elements are not. What for?

If I have this code, it will compile and work as it should:

class MyNumber // Just a class. { static public explicit operator MyNumber(byte b) { return new MyNumber(); } } Decimal d = new Decimal(); MyNumber c1 = (MyNumber)d; 

The perfection of some people is a bit surprising, as there is no explicit expression from decimal to MyNumber . But since there is an explicit order from decimal to byte , as well as an explicit selection from byte to MyNumber , the compiler is kind enough to insert an extra explicit cast into it.

In short: if a programmer uses an explicit cast, the compiler takes the liberty of looking for another explicit cast so that this all happens.

So ... I tried the same with my own classes. Instead of byte and decimal I used MyByte and Mydecimal . The code is as follows:

 class MyDecimal // Simulates a decimal. { static public explicit operator MyByte(MyDecimal a) // Just like in a decimal. { return new MyByte(); } } class MyByte // Simulates a byte. { } class MyNumber // Just a class. { static public explicit operator MyNumber(MyByte b) { return new MyNumber(); } } MyDecimal d = new MyDecimal(); MyNumber c2 = (MyNumber)d; // <== Will not compile! 

The last line will not compile. It gives an error: "It is not possible to convert the type" DoubleExplicitCasts.Program.MyDecimal "to" DoubleExplicitCasts.Program.MyNumber "". Well ... why not ???

So my question is: Why do explicit operators inside a .NET system receive special treatment, and my explicit user statements do not work?

EDIT
I know that this code does not work and the values ​​are not passed from one instance to another, but this does not apply to the point.

+4
source share
2 answers

Well, trivial because it is so defined by the C # standard.

From section 6.4.3:

Custom conversion evaluation never includes more than one custom or canceled conversion operator . In other words, a conversion from type S to type T will never first perform a user-defined conversion from S to X, and then perform a user-defined conversion from X to T.

As for why they decided to limit conversions this way, that's another matter. I am going to suggest two possible reasons:

  • This will allow you to use too many "unexpected" conversions.
  • This will make the compilation process too slow (possible Raman explosion)

but this is only a hypothesis on my part.

+2
source

IMO, which will lead to a "happy debugging" and really, really complex and non-obvious code.

Imagine 3 or more levels of such user transformations and how you will look for the error caused by the transformation in the middle (for example, such a transformation was introduced by mistake or should not be used in this situation).

Thanks for not being supported.

+2
source

Source: https://habr.com/ru/post/1480107/


All Articles