5

私はこの望ましいクラス階層を持っています:

interface IClass
{
    string print(IClass item);
}

class MyClass : IClass
{
    // invalid interface implementation
    // parameter type should be IClass not MyClass
    string print(MyClass item)
    { return item.ToString(); }
}

次のようにジェネリック型を使用してインターフェイスの実装の問題を解決しようとしましたが、成功しませんでした:

interface IClass
{
    string print<T>(T item) where T : IClass;
}

class MyClass : IClass
{
    string print<T>(T item) where T : MyClass
    { return item.ToString(); }
}

私は何をすべきか?

4

4 に答える 4

11

これが違法である理由を理解することは役に立ちます。必要な機能は仮パラメーター型共分散であり、それを提供する言語はほとんどありません。(エッフェル、私はこれを機能として持っていると思います。) 安全ではないため、言語ではあまり見られません! 例を挙げて説明しましょう:

class Animal {}
class Lion : Animal { public void Roar() { } }
class Giraffe : Animal { }
interface IFoo { void M(Animal a); }
class C : IFoo
{
    public void M(Lion lion) { lion.Roar(); }
}
class P
{
    public static void Main()
    {
        IFoo foo = new C();
        foo.M(new Giraffe()); 
    }
}

そして、キリンを鳴らしました。

これらすべての型変換を見ると、合理的に不正にすることができるのは へのマッチングだけC.M(Giraffe)ですIFoo.M(Animal)

現在、仮パラメーターの型の反変性型安全ですが、非常に限られた状況を除いて、C# では合法ではありません。C# がサポートしていない場合は、次のようなことを安全に行うことができます。

interface IBar { void M(Giraffe g); }
class D : IBar
{
    public void M(Animal animal) { ... }
}
class P
{
    public static void Main()
    {
        IBar bar = new D();
        bar.M(new Giraffe()); 
    }
}

そこで何が起こったのですか?IFoo.M は「キリンを飼うことができる」と言い、CM は「実際にはどんな動物でも受け入れることができるので、どんなキリンでも受け入れることができる」と言っています。C# がサポートしていればタイプセーフですが、次の 2 つの方法でしかサポートされていません。

  • 反変の一般的なデリゲートとインターフェイスの変換。
  • デリゲート型への反変メソッド グループ変換。

最初の例は、型の式が同じ論理によってIComparable<Animal>型の変数に割り当てられる可能性があることですIComparable<Giraffe>。2 匹の動物を比較する方法は、2 匹のキリンを比較する方法が必要な場合に使用できます。これは C# 4 で追加されました。

2 番目の例は次のとおりです。

delegate void MyFunction(Giraffe g);
...
D d = new D();
MyFunction myfunc = d.M;

ここでも、Giraffe を受け取る関数が必要であり、任意の Animal を受け取る関数を提供します。この機能は C# 2 で追加されました。

于 2013-04-11T13:41:52.260 に答える
0

IClassをパラメーターとしてメソッドに渡すだけです。

interface IClass
{
  string print(IClass item);
}

class MyClass : IClass
{
  public string print(IClass item)
  { return item.ToString(); }
}
于 2013-04-11T13:26:39.757 に答える