10

次のコードでは、コンパイラ エラー 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;
    }
  }

コンパイラは、一般的なインターフェイスの実装の場合には厳しすぎる、封印されたクラスのみにヒューリスティックを使用しているようです。

(バグという意味で) 本当に厳しすぎるのでしょうか、それともこのエラーには正当な理由があるのでしょうか?

更新:私の質問に対する明確化:コンパイラは、コンパイル時にTOtherとの間に関係があるかどうかを判断できません。が同じか、の基底クラスであるT場合、実行時にキャストは成功し、それ以外の場合はすべて失敗します。これは封印されていてもいなくても同じです。TOtherTFunny<T>

通常、C# コンパイラは、実行時に成功する可能性のあるキャストを防止しません。(たとえば、静的型のインスタンスを にキャストできobjectます。インスタンスがそのインターフェイスを実際に実装していない場合、実行時例外が発生します。) この場合IComparable、なぜそうするのですか?sealed

4

2 に答える 2

4

クラスであるためsealed、プログラマーが継承することはできません。また、オブジェクトをキャストする権限を得るには、継承階層が必要です。

ただし、この場合、キーワードは、どのような場合でも型を指定できない(つまり、継承できない)sealedコンパイラーを保証します。したがって、エラー。TOtherT

sealedキーワードを削除するTOtherと、タイプの可能性がある機会が作成されるため、機能しますT。したがって、エラーはなくなりました。

于 2013-01-29T08:27:32.913 に答える
3

TOtherとTの間には、コンパイル時に決定できる関係はありません。

したがって、基本的には、たとえば、機能しないにキャストIFunny<string>することを期待します。IFunny<DataTable>

于 2013-01-29T08:26:35.523 に答える