The code compiles fine but the third conversion results in an InvalidCastException. And he was quite puzzled by it.

The answer is simple if you think about it, and the exception that’s thrown is a dead giveaway. When you have an object there, the compiler sees that as a downcast (casting from base to a more derived type). The reason is that CusObject<T> is derived from Object (implicitly) and so when the type being converted is Object, it will not call the explicit (or implicit) conversion operator, instead it will generate a castclass IL instruction which will obviously fail.

Error 1 ‘Derived.explicit operator Derived(Base)': user-defined conversions to or from a base class are not allowed

Of course when you use a generic parameter, the compiler cannot anticipate that you’d try doing this, and so it will let you declare the operator. And when you later have an ambiguous situation where you cast from base to derived, it will simply ignore the explicit operator and instead do a downcast.

In the MSDN thread, Louis.fr pointed out the appropriate section in the language spec that talks about this. For those interested it’s 10.10.3. Quoting below:

However, it is possible to declare operators on generic types that, for particular type arguments, specify conversions that already exist as pre-defined conversions.

In cases where a pre-defined conversion exists between two types, any user-defined conversions between those types are ignored.