Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get a compilation error when casting a sealed class to an interface it might implement?

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?

like image 557
Fabian Schmied Avatar asked Jan 29 '13 08:01

Fabian Schmied


1 Answers

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.

like image 107
mihirj Avatar answered Sep 29 '22 20:09

mihirj