返回的派生类多于接口指定的派生类

本文关键字:派生 接口 于接口 返回 | 更新日期: 2023-09-27 18:21:10

我正在尝试创建一组具有不同抽象级别的类。我将在这里使用Vector示例。

我的目标是,我的类的用户可以选择要使用的抽象级别,也就是说,他们可能不想使用更派生的类。

interface IVector
{
    Vector A();
}
interface ISparseVector : IVector
{
    new SparseVector A();
}

现在,我实现类如下:

class Vector : IVector
{
    public Vector A() { return new Vector(); }
}
class SparseVector : Vector,ISparseVector
{
    public new SparseVector A() { return new SparseVector(); }
}

这一切都很好。然而,当基类是抽象的时,例如:

abstract class Vector : IVector
{
    public abstract Vector A();
}
class SparseVector : Vector,ISparseVector
{
    public SparseVector A() { return new SparseVector(); } // Hides abstract member.
}

我得到一个编译错误,说派生方法将抽象方法隐藏在Vector中。你知道怎么绕过这个吗?

返回的派生类多于接口指定的派生类

您想要的特性称为"返回类型协方差",它不是C#的特性。返回类型协方差是一种功能,您可以使用一个返回Animal的虚拟方法,然后用一个返回Giraffe的方法覆盖它。

这样做是类型安全的,有些语言确实有这个功能,例如C++,但C#没有,我们也没有添加它的计划。您的重写方法必须标记为override,并且它必须在名称、形式参数类型和返回类型上完全匹配。

原因是在Vector类的第一个示例中,您没有为A()方法指定访问级别。这意味着它是一个私有方法,这是默认的。您可以在SparseVector类中使用new关键字来避免此错误。

首先,您应该看看这个线程,它指定了为什么不能使用抽象构造函数。

为什么可以';我不能在抽象C#类上创建一个抽象构造函数吗?

然后,您应该在Vector类中放入一个抽象方法,该方法实际上可以被重写以提供实现,就像抽象方法应该是的那样。

不能像现在这样混合抽象方法和接口方法。如果您声明"Vector"抽象并覆盖A()的实现,那么您将覆盖抽象类中的"Vector A()",但这不会实现返回类型为ISparseVector的接口ISparseVector.Vvector。

您的用例似乎并不要求"Vector"是抽象的。