繁体   English   中英

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

[英]How to implement a abstract nongeneric base class, for generic derived classes in 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有更多的成员。

谢谢!

您要求的是返回类型协方差,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();
    }
}

不确定你想要在这里实现什么。 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;
        }
    }

要使其工作,您可以使您的基类通用:

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;
    }
}

为什么不:

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;
    }
}

您可以返回在AObject属性中实现ISomeInterface接口的任何类型,因为IEnumearable<T>是协变的,您可以返回任何可枚举的ISomeInteface实现的类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM