我正在编写一个库,用于将一堆子对象渲染到屏幕上。这个子对象是抽象的,旨在让该库的用户从这个抽象类派生他们自己的子类。
public abstract class Child : IRenderable {}
public interface IParent<T> where T : Child
{
IEnumerable<T> Children { get; }
}
问题在于我没有IParent列表可以使用,相反,我有一堆IRenderables。库的用户应该编写类似以下的内容:
public class Car : IRenderable { }
public class Cow : IRenderable, IParent<Calf> { }
public class Calf : Child { }
// note this is just an example to get the idea
public static class App
{
public static void main()
{
MyLibraryNameSpace.App app = new MyLibraryNameSpace.App();
app.AddRenderable(new Car()); // app holds a list of IRenderables
app.AddRenderable(new Cow());
app.Draw(); // app draws the IRenderables
}
}
在Draw()函数中,这个库 应该 进行强制类型转换并检查IRenderable是否也是IParent。然而,由于我不了解Calf,我不知道如何将Cow进行类型转换。
// In Draw()
foreach(var renderable in Renderables)
{
if((parent = renderable as IParent<???>) != null) // what to do?
{
foreach(var child in parent.Children)
{
// do something to child here.
}
}
}
我该如何解决这个问题?这与协变泛型有关吗或者是其他什么东西(我不熟悉协变的概念)?
IParent<object>
不合法(它不满足T : Child
的条件),而且它并不是真正的 超类 - 相反,它允许编译器和运行时利用协变性。 - Marc Gravell