1

そのため、問題なくコンパイルできるジェネリックを広範囲に使用する Java コードがいくつかあります。次のようにC#に移植しました。

interface IFoo1 { }
interface IFoo2 { }

interface IBar<T, K>
    where T : IFoo1
    where K : IFoo2 {
    List<T> GetFoo1s();
    void AddAFoo1(T foo1);

    List<K> GetFoo2s();
    void AddAFoo2(K foo2);
}

interface IBlip<T>
    where T : IBar<IFoo1, IFoo2> {
    T DoBlip(string input);
    void DoBlip2(T input);
}

interface IConverter<T, K>
    where T : IBar<IFoo1, IFoo2>
    where K : IBar<IFoo1, IFoo2> {
    K Convert(T input);
}

class FooA1 : IFoo1 { }
class FooB1 : IFoo1 { }

class FooA2 : IFoo2 { }
class FooB2 : IFoo2 { }

class BarA : IBar<FooA1, FooA2> {
    public List<FooA1> GetFoo1s() { return null;  }
    public void AddAFoo1(FooA1 foo1) { }
    public List<FooA2> GetFoo2s() { return null; }
    public void AddAFoo2(FooA2 foo2) { }
}

class BarB : IBar<FooB1, FooB2> {
    public List<FooB1> GetFoo1s() { return null; }
    public void AddAFoo1(FooB1 foo1) { }
    public List<FooB2> GetFoo2s() { return null; }
    public void AddAFoo2(FooB2 foo2) { }
}

class BlipA : IBlip<BarA> {
    public BarA DoBlip(string input) { return null; }
    public void DoBlip2(BarA input) { }
}

class BlipB : IBlip<BarB> {
    public BarB DoBlip(string input) { return null; }
    public void DoBlip2(BarB input) { }
}

class ConverterImplementation : IConverter<BarA, BarB> {
    public BarB Convert(BarA input) {
        return null;
    }
}

これをコンパイルすると、たとえば、ConverterImplementation を使用すると、BarA を暗黙的に IBar に変換できないことがわかります。ここで根本的に欠けているものがあると思います。誰かがそれに光を当てることができますか?ありがとう。

4

2 に答える 2

4

ジェネリック型パラメーターは、デフォルトでは反変でも共変でもありませんが、「in」および「out」キーワードを使用してどちらか一方を作成できます。

IBar <T、K>の場合、両方のタイプパラメーターが入力と出力の両方として使用されるため、それらを反変または共変にすることはできません。Tが入力のみに使用されKが出力のみに使用されるインターフェースと、Tが出力のみに使用されKが入力のみに使用されるインターフェースの、2つのインターフェースにリファクタリングした場合、各タイプのパラメーターを共変または反変ベースにすることができます。その使用法について。

于 2013-03-22T21:10:06.380 に答える