2

非常不言自明的问题,很高兴得到任何答案。对我来说这没有意义。我不在乎丢失信息。我只想以某种方式将所有继承 IRenderable 的列表连接到一个列表中,然后在其上调用 IRenderable 方法。我有一种感觉,这是我忘记的一些基本编程规则......

编辑:这是代码:

interface IRenderable
{
    void Render();
}
interface IScreen : IRenderable
{
}
public List<IScreen> Screens = new List<IScreen>();
List<IRenderable> renderList = new List<IRenderable>();
renderList = ((List<IRenderable>)Screens; // error: cannot convert type IScreen to IRenderable

edit2:顺便说一句,我安装了 .net 4.0,但参考仍然是 System.dll 版本 2.0.5.0

4

3 回答 3

2

我的猜测是你真的想从List<IScreen>toList<IRenderable>或类似的东西转换。

由于泛型不变性,您根本无法在 .NET 4 之前执行此操作。在 .NET 4 中,您可以在适当的地方为接口和委托执行此操作。特别是,您可以从 转换IEnumerable<IScreen>IEnumerable<IRenderable>。如果您只是想连接一个列表,那应该没问题 - 您应该能够List<T>.AddRange与您的每个列表一起使用......但同样,这仅适用于 C# 4。C# 4 中的另一个选项类似于:

var combined = firstList.Concat<IRenderable>(secondList).ToList();

作为为什么这并不总是安全的示例( C# 4 中允许的使用是安全的),请考虑以下代码:

List<Apple> apples = new List<Apple> { new Apple(...) };
List<Fruit> fruit = apples;
fruit.Add(new Orange());

现在apples引用的列表包含一个橙色!从类型安全的角度来看,这显然不是一件好事。

正如 driis 所说,如果您可以提供更多详细信息(例如您拥有什么以及您想要什么),我们应该能够提供更多帮助。

于 2010-05-24T10:11:32.853 回答
1

List<T0>是不可铸造的List<T1>。您应该对列表的每个元素进行强制转换。IEnumarable 的 Cast 扩展是这样做的:

List<IScreen> Screens = new List<IScreen>();
List<IRenderable> renderList = Screens.Cast<IRenderable>().ToList();
于 2010-05-24T11:30:42.423 回答
1

你没有提供很多细节。但是让我们假设你有:

IRenderable {}

IScreen : IRenderable {}

private List<IRenderable> ConcatLists(IEnumerable<IRenderable> first, IEnumerable<IRenderable> second) { ... }

现在,在 C#4 之前的 C# 版本中,您将无法使用 IEnumerable<IScreen> 直接调用 ConcatLists 方法。其原因称为协变和逆变。在框架 4 中, IEnumerable<T> 被声明为协变的,这意味着它可以隐式转换为 IEnumerable ,其中 T 的类型较小(在您的情况下为 IRenderable )。

如果你想在 C#3 中调用这样的方法,你可以使用扩展方法来帮助你。

这可能是:

ConcatLists(first.Cast<IRenderable>(), second);

如果“first”被声明为 IRenderable 类型。

于 2010-05-24T10:13:04.043 回答