在基础 class 方法中使用未来的 subclass 类型

Use a future subclass type in a base class method

假设我有一个基础 class BaseFoo 和一个方法来处理完全由 BaseFoo 组成的数据结构:

public class BaseFoo { // FWIW, in my "real" example, this is an abstract base class
    public void Func(IEnumerable<BaseFoo> data) {
        // impl.
    }
}

然后我有一些子classes, Bar and Baz:

public class Bar : BaseFoo {}
public class Baz : BaseFoo {}

但我意识到我对 Func 的参数包含所有相同类型的对象并且该类型与子 class 匹配非常重要!继承的Bar.Func方法如果被传new[] {new Bar(), new Baz()}.

,灾难可能降临

如何在 BaseFoo.Func 的声明中强制执行此操作? (我不能使用泛型 <T> where T : BaseFoo,因为编译器只会将 BaseFoo 用于 T,最后一段末尾的错误示例会编译。)

编辑: 也许是一个更好的例子:我想在我的 Bar 子 class 中存储 Bar 的列表,Baz 也是如此。但是我想在 FooBase 中为 List<this.GetType()> 写一个声明,我很清楚这不会编译。我只是在寻找一种在基础 class.

中使用任意子 class 类型 的方法

一种方法是使用 泛型

例子

public class BaseFoo<T> where T : BaseFoo<T>
{
    public void Func(IEnumerable<T> data) { }
}

public class Bar : BaseFoo<Bar> {}
public class Baz : BaseFoo<Baz> {}

这意味着

var bar = new Bar()
bar.Func(new List<bar>()) // can only ever take an enumerable of bar

免责声明:这忽略了您在概念上或其他方面可能遇到的任何其他问题

更新

我已经添加了 where T : BaseFoo<T> 这被称为 Curiously recurring template pattern in C++, inspired by the comments from charlieface, also Eric Lippert has written about this in one of his blogs Curiouser and curiouser