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接口的类型,AObject并且因为IEnumearable<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 回答