2

我正在编写一个具有用于实现数据类型的 OOP 结构的 SDK;

  1. 首先是一个界面
  2. 然后是一个抽象实现
  3. 最后是一个抽象的通用实现

人们可以选择实现接口,或者从任何一个类派生。

public interface IGoo
{
  IGoo Duplicate();
  ...
}
public abstract class Goo : IGoo
{
  IGoo IGoo.Duplicate() {
    return Duplicate();
  }
  abstract public Goo Duplicate();
  ...
}
public abstract class Goo<T> : Goo
{
  abstract public Goo<T> Duplicate(); ??????
  ...
} 

我想重新实现 Duplicate 方法,以便它始终返回可能的最具体的类型。即,当您在 IGoo 实例上调用 Duplicate 时,您会得到另一个 IGoo。如果你在 Goo 上调用它,你会得到 Goo,如果你在 -say- Goo<int> 上调用它,你会得到 Goo<int>。并且所有 Duplicate() 方法总是调用最具体的实现。

这可能吗?只有当您可以显式实现接口时才有可能?在这种情况下,我不应该让 Goo<int> 从 Goo 派生,而是让它实现 IGoo 并键入所有低级功能两次?

4

2 回答 2

1

下面的呢?

public interface IObj
{
    IObj Duplicate();
}

public abstract class Obj : IObj
{
    public Obj()
    {

    }
    public virtual IObj Duplicate()
    {
        return this;
    }
}

public abstract class ObjT<T> : Obj
{
    public ObjT()
    {

    }
    public override IObj Duplicate()
    {
        return this;
    }
}

public class ObjImpl : Obj
{

}

public class ObjTImpl : ObjT<int>
{

}

我知道您希望它在任何继承类中返回最具体的类型,但实际上是这样。它将继承类型装箱到接口中(或者如果您在哪里返回对象而不是接口类型,则为原始对象。如果您在控制台应用程序中运行以下测试,您将看到表示正确的类型:

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjImpl a = new ObjImpl();

            ObjTImpl b = new ObjTImpl();

            Console.WriteLine(a.Duplicate().GetType());
            Console.WriteLine(b.Duplicate().GetType());

            Console.ReadLine();
        }
    }
}

// outputs:

// ObjImpl
// ObjTImpl

重新定义摘要的摘要的想法与抽象多态性的目的背道而驰。如果派生类型不打算实现继承的抽象成员,它们不应该继承它。

尽管我在上面给出的示例需要强制转换才能访问任何特定于子类的成员,但这将是在这种方法中执行此操作的正确方法。运行时需要知道它应该处理什么类型。

总是有你可以玩弄的动态,但老实说,我没有玩过泛型和继承的动态,因为我怀疑我会让我的编译器哭泣,当它哭泣时,我会哭泣,有点内心深处。 .. 哈哈

于 2013-12-21T03:34:03.720 回答
1

只有当您显式实现接口时才有可能。这是因为方法的返回类型不是其签名的一部分——编译器在重载时会检查它。因此,其他仅返回类型不同的相同方法在语法上是不可能的。

于 2013-12-21T05:47:04.500 回答