将密封类转换为可能实现的接口时,为什么会出现编译错误?

Fab*_*ied 9 c# generics compiler-errors

以下代码给出了编译器错误CS0030(使用VS 2012的C#编译器编译),尽管转换可能在运行时成功.删除sealed关键字,使用as强制转换或添加中间强制转换object会使错误消失.

  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;
    }
  }
Run Code Online (Sandbox Code Playgroud)

在我看来,编译器只使用密码类的启发式,在通用接口实现的情况下过于严格.

它真的太严格了(在一个错误的意义上),还是有充分的理由发生这个错误?

更新:对我的问题的澄清:编译器无法确定编译时TOtherT编译时是否存在关系.在运行时,如果TOther是相同的或基类,则转换将成功,T并且在所有其他情况下它将失败.无论是否Funny<T>密封,都是如此.

C#编译器通常不会阻止在运行时可能成功的强制转换.(例如,我可以将静态类型的实例转换objectIComparable,如果实例没有真正实现该接口,则会导致运行时异常.)为什么在这种sealed情况下会这样做?

mat*_*ieu 3

TOther 和 T 之间没有可以在编译时确定的关系。

因此,基本上您会期望强制转换IFunny<string>为 a IFunny<DataTable>,例如,这是行不通的。