如何为c#中的泛型派生类实现抽象非泛型基类?

时间:2012-11-11 18:23:24

标签: c#

这就是我希望我的类看起来像,但这段代码不会编译。我如何使它工作?

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 个答案:

答案 0 :(得分:2)

您要求的是返回类型协方差,C#不支持此功能(有关详细信息,请参阅this答案)。你必须以某种方式修改你的类,但你没有说明什么是可接受的。这是一种不改变公共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();
    }
}

答案 1 :(得分: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;
        }
    }

答案 2 :(得分: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;
    }
}

答案 3 :(得分: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属性中实现AObject接口的任何类型,因为IEnumearable<T>是协变的,您可以返回任何可枚举的ISomeInteface实现的类。