3

クラス B で派生させる予定の型パラメーター T を持つジェネリック抽象クラス A を作成しています。

A には、ジェネリック関数を持つクラス C のインスタンスであるデータ メンバー mX があります。この汎用関数 GetAllOfType() には、1 つの型パラメーター T があります。この型パラメーターは、3 番目のクラス D に制約されます。GetAllOfType() は、D の派生クラスのインスタンスを含む D のインスタンスのコンテナーを検索し、タイプ T のサブセット (したがって、D への制約)。

クラス D 自体には特定のデータ メンバー int mY はありませんが、E や F など、D の一部の派生クラスにはあります。

public class D
{
}

public class E : D
{
    public int mY;
}

public class F : D
{
    public int mY;
}

public class C
{
    public T[] GetAllOfType<T>() where T : D
    { ... }
}

public class A<T>
{
    private C mX;
    ...
}

public class B : A<E>
{
    ...
}

だからここで私の問題が始まります:

クラス B がクラス A を継承して実装するために使用するパラメーターの型は、D の派生クラスです。GetAllOfType() を介して列挙し、型 E、F、またはその他のメンバー mY にアクセスする関数 Foo をクラス A に記述しようとしています。 mY を持つメンバー。

public class A<T>
{
    private C mX;

    protected Foo()
    {
        foreach (var c in mX.GetAllOfType<T>())
        {
            c.mY = 0;
        }
    }
}

public class B : A<E>
{
    public Bar()
    {
        Foo();
    }
}

ただし、問題は GetAllOfType() が制約されていることであり、クラス A も制約していないというエラーが発生します。

私はそのように A を制約しようとしました:

public class A<T> where T : D

しかし、次の行に沿ってコンパイル時エラーが発生しています。

mY T' does not contain a definition for' と入力し、拡張メソッドmY' of typeT' が見つかりませんでした (using ディレクティブまたはアセンブリ参照がありませんか?)

また、複数の派生クラスに制約しようとしました:

public class A<T> where T : E, F

しかし、次の行に沿ってエラーも発生しています。

クラス型制約 'F' は、他の制約より前にリストする必要があります。型制約を制約リストの先頭に移動することを検討してください

私はそれらを切り替えてみました:

public class A<T> where T : F, E

同様に、結果は同じエラーになりますが、F が E に置き換わっています。

私が試みていることは可能ですか?私は何を間違っていますか?

繰り返しますが、クラス C、D、E、および F については何も変更できません。

4

1 に答える 1

2

A のジェネリック パラメーターに制約を追加すると、

public class A<T> where T : D

2 番目のエラーが発生する理由Type T' does not contain a definition for mY' and no extension method mY' of typeT' could be found (are you missing a using directive or an assembly reference?)は、当然のことながら、D には mY がなく、派生クラス E と F しかないためです。

public class A<T> where T : E, F

機能しないのは、基本クラスの型の制約を 1 つしか指定できないためです (C# には多重継承がありません)。それ以上の制約は、インターフェイス、または次のようなものでなければなりませclassnew()

これらのクラスについて本当に何も変更できない場合、私が知る限り、あなたが達成しようとしていることは不当に難しいかもしれません。私はいくつかの醜い方法 (リフレクション、または多くのキャスト) を考えることができますが、それは正しい道ではありません。たぶん、私が見逃している賢い何かがあります。mY プロパティを持つインターフェイス (または中間クラス) を導入し、それを E と F に継承させることができれば素晴らしいことです。次に、代わりに T をそれに制約することができD、すべてがホンキードーリーになります。Dそうしないと、実行時を除いて、あなたがどのようなものを扱っているかを知る方法がわかりません。

于 2012-06-13T23:38:45.257 に答える