gpt4 book ai didi

C# 类型转换为通用接口(interface)

转载 作者:太空狗 更新时间:2023-10-29 20:08:12 25 4
gpt4 key购买 nike

我正在编写一个库,用于将一堆 child 对象渲染到屏幕上。子对象是抽象的,目的是让这个库的用户从这个抽象类中派生出他们自己的 child 。

public abstract class Child : IRenderable {}

public interface IParent<T> where T : Child
{
IEnumerable<T> Children { get; }
}

复杂的是我没有要使用的 IParent 列表,相反,我有一堆 IRenderable。图书馆的用户应该写这样的东西:

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<T>返回 T 类型的项目,您可以使用 out modifier 使其协变:

public interface IParent<out T> where T : Child
{
IEnumerable<T> Children { get; }
}

这将使 IParent<anything>可转换为 IParent<Child> :

IParent<Child> parent = renderable as IParent<Child>; // works for Cow

请注意,协方差仅在您仅返回 T 类型的对象时有效。 (简单地说)。例如,只要您添加 AddChild(T) IParent 的方法接口(interface),协变性必须中断(= 编译器会提示),否则,可能会编写以下类型不安全的代码:

IParent<Child> parent = renderable as IParent<Child>;
parent.AddChild(new Kitten()); // can't work if parent is really a Cow.

关于C# 类型转换为通用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10135866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com