0

これは私のクラスをどのように見せたいかですが、このコードはコンパイルされません。どうすればそれを機能させることができますか?

public interface ISomeInterface
{
    string AMember { get; }
}
public abstract class BaseClass
{
    public abstract ISomeInterface AObject { get; }
    public abstract IEnumerable<ISomeInterface> AMethod();
}

public class DerivedClass<T> : BaseClass where T : ISomeInterface
{
    public T AObject { get; private set; }
    public IEnumerable<T> AMethod()
    {
        return null;
    }
}

コンパイラエラー

「Delfin.Accountancy.DerivedClass」は、継承された抽象メンバー「Delfin.Accountancy.BaseClass.AObject.get」を実装していません。

「Delfin.Accountancy.DerivedClass」は、継承された抽象メンバー「Delfin.Accountancy.BaseClass.AMethod()」を実装していません。

C#5.0で実行しています。

ノート

私は最も明白な実装を試しましたが、それらのいずれも、基本クラスを実装し、強く型付けされたメンバーを一度に公開することを可能にします。

基本クラスに静的メソッドを作成し、派生クラスのすべての場合に機能する可能性のある拡張メソッドも作成するため、基本クラスをジェネリックにしたくありません。

また、実世界の場合、TにはISomeInterfaceよりも多くのメンバーがあるため、派生クラスは汎用である必要があります。

ありがとう!

4

4 に答える 4

2

求めているのはリターン型共分散と呼ばれ、C#はこれをサポートしていません(詳細については、この回答を参照してください)。なんらかの方法でクラスを変更する必要がありますが、何が許容できるかを示していません。これは、パブリックAPIを変更せずに、抽象メソッドを保護されたメソッドに変更する方法です。

public interface ISomeInterface
{
    string AMember { get; }
}

public abstract class BaseClass
{
    public ISomeInterface AObject { get { return GetAObjectImpl(); } }     
    public IEnumerable<ISomeInterface> AMethod() { return AMethodImpl(); }

    protected abstract ISomeInterface GetAObjectImpl();
    protected abstract IEnumerable<ISomeInterface> AMethodImpl();
}

public class DerivedClass<T> : BaseClass where T : ISomeInterface
{
    public new T AObject { get; private set; }

    public new IEnumerable<T> AMethod() { return Enumerable.Empty<T>(); }

    protected override ISomeInterface GetAObjectImpl() 
    {
        return AObject;
    }

    protected override IEnumerable<ISomeInterface> AMethodImpl()
    {
        return AMethod();
    }
}
于 2012-11-11T19:00:29.333 に答える
0

なぜだめですか:

public interface ISomeInterface
{
    string AMember { get; }
}
public abstract class BaseClass
{
    public abstract ISomeInterface AObject { get; protected set; }
    public abstract IEnumerable<ISomeInterface> AMethod();
}

public class DerivedClass : BaseClass
{
    public override ISomeInterface AObject { get; protected set; }
    public override IEnumerable<ISomeInterface> AMethod()
    {
        return null;
    }
}

プロパティにISomeInterfaceインターフェイスを実装する任意の型を返すことができます。また、共変であるため、実装されたクラスの列挙可能なものを返すことができます。AObjectIEnumearable<T>ISomeInteface

于 2012-11-11T18:56:55.930 に答える
0

ここで何を達成しようとしているのかわからない。DerivedClass AObjectとIEnumerableは、基本クラスの宣言を効果的に非表示にします。派生クラスのシグネチャがそのジェネリックパラメータとしてインターフェイスを使用するようにする理由は何ですか?

これはコンパイルされます:

    public interface ISomeInterface
    {
        string AMember { get; }
    }
    public abstract class BaseClass
    {
        public abstract ISomeInterface AObject { get; protected set; }
        public abstract IEnumerable<ISomeInterface> AMethod();
    }

    public class DerivedClass<T> : BaseClass where T : ISomeInterface
    {
        public override ISomeInterface AObject { get; protected set; }
        public override IEnumerable<ISomeInterface> AMethod()
        {
            return null;
        }
    }
于 2012-11-11T18:33:59.673 に答える
0

それを機能させるには、基本クラスをジェネリックにすることができます。

public interface ISomeInterface
{
    string AMember { get; }
}
public abstract class BaseClass<T> where T : ISomeInterface
{
    public abstract T AObject { get; protected set; }
    public abstract IEnumerable<T> AMethod();
}

public class DerivedClass<T> : BaseClass<T> where T : ISomeInterface
{
    public override T AObject { get; protected set; }
    public override IEnumerable<T> AMethod()
    {
        return null;
    }
}
于 2012-11-11T18:34:00.147 に答える