4

私は自分が抱えている問題を解決する方法を考えていましたが、それがうまくいくかどうかはわかりません。

Aという基本クラスと3つのサブクラスB、C、Dがあるとします。

        A
        ^
-----------------
|       |       |
B       C       D

また、X、Y、Zの3つのクラスがあります。

私のシステムオブジェクトでは、タイプB、C、DがタイプAとして渡され、通常、タイプB、C、DのオブジェクトをオブジェクトX、Y、またはZのいずれかに変換する必要があります(キャストではないため、手動で変換します。完全に異なります)。

したがって、オブジェクトタイプAをタイプX、Y、またはZに変換するには、最初にサブタイプをチェックしてから、サブタイプに応じてAオブジェクトに関するいくつかの操作の結果を使用してX、Y、またはZオブジェクトを初期化する必要があります。

明示的なキャスト操作をAからX、Y、またはZにオーバーロードすることを考えましたが、それらを変換したときと同じプロセスを実行していましたが、それから考えました...ポリモーフィズムを使用して、Bからのキャストをオーバーロードすることは可能でしょうか? CとDは、AIの新しいサブタイプを追加するときに、Aのキャストコードを変更する必要がないという方法ですか?(新しいサブタイプに明示的なキャストオーバーロードを追加するだけです)

何か紛らわしいことがあれば申し訳ありませんが、きちんと説明していただければ幸いです。

注:X、Y、Zのキャストオーバーロードを追加します

4

3 に答える 3

3

X、Y、およびZが共通のタイプTから派生していると仮定して、Aで抽象変換メソッドを宣言します。

public abstract class A
{
    public abstract T Convert();
}

BでオーバーライドしてXを返し、CでオーバーライドしてYを返し、DでオーバーライドしてZを返します。このように、各タイプは独自の変換されたタイプを返す責任があり、新しいタイプが追加した。

于 2012-06-17T18:35:18.713 に答える
2
abstract class A
{
    public abstract object Convert();
}
class B : A
{
    public override object Convert()
    {
        return ConvertToX();
    }
    public X ConvertToX()
    {
        return new X();
    }
}
void SomeMethod()
{
    A o = new B();
    var result = (X)o.Convert();
}

これにより、クラスが、であることがわかっている場合(オーバーライドできないため、Bを介して)、およびそれがであることがわかっている場合にのみ、厳密に型指定された結果を得ることができます。明示的な変換は、使用している変数の静的タイプに基づいてのみ発生する可能性があるため、あなたが尋ねたように、キャストを使用してこれを行う良い方法は実際にはありません。ConvertToXX Convert()object Convert()objectA


(@svickは、以下の私の前のコードの大きな欠陥を指摘しました。これは、オブジェクトがであることがわかっているだけでは、簡単に何もできないということAですA<T>。用途があります:)

interface IConvertible<out T>
{
    T Convert();
}
abstract class A
{
}
abstract class A<T> : A, IConvertible<T>
{
    public abstract T Convert();
    public static explicit operator T(A<T> a)
    {
        return a.Convert();
    }
}
class B : A<X>
{
    public override X Convert()
    {
        // TODO implement this
    }
}

また、複数のタイプに変換できるタイプがある場合は、次のようにすることができます。

class B : A<X>, IConvertible<Y>
{
    public override X Convert()
    {
        throw new NotImplementedException();
    }
    Y IConvertible<Y>.Convert()
    {
        throw new NotImplementedException();
    }
}

または:

class B : A, IConvertible<X>, IConvertible<Y>
{
    X IConvertible<X>.Convert()
    {
        throw new NotImplementedException();
    }
    Y IConvertible<Y>.Convert()
    {
        throw new NotImplementedException();
    }
}
于 2012-06-17T18:33:12.567 に答える
2

タイプのキャスト演算子でAインスタンスの仮想(または抽象?)インスタンスメソッドを呼び出し、のAサブクラスごとにそれをオーバーライドすることができますAXただし、このソリューションの相互基本クラスから派生する必要があるため、キャスト演算子はその基本クラスを結果タイプとして持つことができますYZ

public abstract class A
{
    protected abstract W ConvertToW();

    public static explicit operator W(A a)
    {
        return a.ConvertToW();
    }
}

この例では、は、、およびWの基本クラスです。XYZ

于 2012-06-17T18:33:22.787 に答える