The following code gives a compiler error CS0030 (compiled with the C# compiler of VS 2012), although the cast might succeed at runtime. Removing the sealed
keyword, using an as
cast, or adding an intermediate cast to object
makes the error go away.
public interface IFunny<out T> { }
public sealed class Funny<T> : IFunny<T>
{
public IFunny<TOther> Cast<TOther> ()
{
// error CS0030: Cannot convert type Funny<T>' to 'IFunny<TOther>'.
return (IFunny<TOther>) this;
}
}
It seems to me the compiler uses a heuristic for sealed classes only that is too strict in the case of generic interface implementations.
Is it really too strict (in the sense of a bug), or is there a good reason for this error?
Update: A clarification to my question: The compiler cannot determine whether there is a relationship between TOther
and T
at compile time. The cast would succeed, at runtime, if TOther
is the same or a base class of T
, and it would fail in all other cases. This is true no matter whether Funny<T>
is sealed or not.
The C# compiler does not normally prevent casts that might succeed at runtime. (For example, I can cast an instance of static type object
to IComparable
, causing a runtime exception if the instance doesn't really implement that interface.) Why does it do so in this sealed
case?
Since it is sealed
class, it cannot be inherited down the line by programmer. And in order to have the privileges of casting the objects, you need an inheritance hierarchy.
However, in this case the sealed
keyword guarantees the compiler that TOther
cannot be of type T
in absolutely any case (i.e. It cannot be inherited). Hence the error.
Removing the sealed
keyword works as it creates opportunity that TOther
may be of type T
. Hence the error is gone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With