5

私のクラス構成を見てください。相続をもっと楽しみたいと思います。

まず、基本抽象クラスがあります。

public abstract class PolicyDetailed
{
    internal abstract DataContainer GetActiveAsset();
}

次に、汎用的な別の抽象クラスがあります。

public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer
{
    internal new abstract T GetActiveAsset();
}

最後に、特定のポリシークラスがあります。AccidentContainerはDataContainerから継承します。

public class PolicyAccident : PolicyDetailed<AccidentContainer>
{
    internal override AccidentContainer GetActiveAsset()
    {
        return null;
    }
}

コンパイル中に、次のエラーが発生します。

'PolicyAccident' does not implement inherited abstract member 'PolicyDetailed.GetActiveAsset()'  

ここで機能させるためにどの修飾子を使用すべきかわかりません。達成したいことも書く必要があるかもしれません。さまざまなタイプのDataContainer(AccidentContainer、TravelContainerなど)でPolicyDetailedから継承するさまざまなタイプ(PolicyAccident、PolicyTravelなど)のポリシーオブジェクトのコレクションがあります。特定のタイプを知らずに、PolicyDetailedを介して参照せずに、それぞれで「GetActiveAsset」メソッドを呼び出したいと思います。同時に、各クラスが特定のDatacontainerサブクラスを返すようにします。それは可能ですか?

4

1 に答える 1

6

問題は、同じシグニチャを持つ他のメソッドを宣言するのと同じクラスの非ジェネリックメソッドをオーバーライドできないことです。

いくつかのオプションがあります:

  • 最も簡単なのは、2つのメソッドに異なる名前を付けることです。PolicyDetailed<T>次に、新しい抽象メソッドに委任するだけの実装を提供できます。

    public abstract class PolicyDetailed
    {
        internal abstract DataContainer GetActiveAsset();
    }
    
    public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer
    {
        internal abstract T GetActiveAssetGeneric();
    
        internal override DataContainer GetActiveAsset()
        {
            return GetActiveAssetGeneric();
        }
    }
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer>
    {
        internal override AccidentContainer GetActiveAssetGeneric()
        {
            return null;
        }    
    }
    
  • 別のレベルの継承を導入して、ブリッジングの目的で新しいメソッド名を導入することもできます。これはかなり醜いです:

    public class DataContainer {}
    public class AccidentContainer : DataContainer{}
    
    public abstract class PolicyDetailed
    {
        internal abstract DataContainer GetActiveAsset();
    }
    
    // This only exists to satisfy the base class abstract member,
    // but at the same time allowing PolicyDetailed<T> to introduce
    // a new member with the same name.
    public abstract class PolicyDetailedBridge<T> : PolicyDetailed
        where T : DataContainer
    {
        protected abstract T GetActiveAssetGeneric();
    
        internal override DataContainer GetActiveAsset()
        {
            return GetActiveAssetGeneric();
        }
    }
    
    public abstract class PolicyDetailed<T> : PolicyDetailedBridge<T>
        where T : DataContainer
    {
        protected sealed override T GetActiveAssetGeneric()
        {
            // Call the *new* abstract method. Eek!
            return GetActiveAsset();
        }
    
        internal abstract new T GetActiveAsset();
    }
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer>
    {
        internal override AccidentContainer GetActiveAsset()
        {
            return null;
        }            
    }
    
  • 代わりに、非ジェネリックPolicyDetailedクラスをインターフェイスにし、明示的なインターフェイス実装を使用して新しい抽象メソッドを宣言し、それでもインターフェイスを実装することができます。

于 2012-08-05T20:29:55.407 に答える