6

考えてみてください。私には次の3つのクラス/インターフェースがあります。

class MyClass<T> { }

interface IMyInterface { }

class Derived : IMyInterface { }

MyClass<Derived>そして、私はaMyClass<IMyInterface>またはその逆にキャストできるようにしたいと思います:

MyClass<Derived> a = new MyClass<Derived>();
MyClass<IMyInterface> b = (MyClass<IMyInterface>)a;

しかし、試してみるとコンパイラエラーが発生します。

Cannot convert type 'MyClass<Derived>' to 'MyClass<IMyInterface>'   

私がこれを行うことができない非常に正当な理由があると確信していますが、私はそれを考えることができません。

私がこれをやりたい理由について-私が想像しているシナリオは、MyClass<Derived>多くの厄介なキャストを回避するためにインスタンスを操作するのが理想的ですが、インスタンスを受け入れるインターフェイスにインスタンスを渡す必要がありますMyClass<IMyInterface>

だから私の質問は2つあります:

  • これら2つのタイプの間でキャストできないのはなぜですか?
  • MyClass<Derived>これをにキャストできる一方で、インスタンスを操作することの素晴らしさを維持する方法はありますMyClass<IMyInterface>か?
4

2 に答える 2

5

C# はインターフェイスとデリゲートの型パラメーターの共分散のみをサポートするため、これは機能しません。型パラメーターが出力位置にのみ存在する場合 (つまり、クラスからそのインスタンスを返すだけで、それを引数として受け入れない場合)、次のようなインターフェイスを作成できます。

interface IClass<out T> { }
class MyClass<T> : IClass<T> { }

これにより、次のことが可能になります。

IClass<Derived> a = new MyClass<Derived>();
IClass<IMyInterface> b = a;

正直なところ、それはあなたが得ようとしているのとほぼ同じであり、これには C# 4 コンパイラが機能する必要があります。

于 2010-04-19T23:56:25.353 に答える
3

一般的にこれを行うことができない理由は、ほとんどのクラスが単純な空の例ではないためです。それらにはメソッドがあります:

class MyClass<T> 
{
    static T _storage;

    public void DoSomethingWith(T obj)
    {
        _storage = obj;
    }
}

interface IMyInterface { }

class Derived : IMyInterface { }

MyClass<Derived> a = new MyClass<Derived>();

ここで、を受け入れ、それを型の静的変数に格納aするメソッドがあります。DoSomethingWithDerivedDerived

MyClass<IMyInterface> b = (MyClass<IMyInterface>)a;

それが許可された場合、を実装するものをすべて受け入れるbメソッドがあるように見え、それをタイプの静的変数に内部的に格納しようとします。これは、が参照するオブジェクトと実際には同じであるためです。DoSomethingWithIMyInterfaceDeriveda

これで、Derived格納型の変数ができました...誰が何を知っているのでしょうか。

于 2010-04-20T00:12:57.920 に答える