非常自我解释的问题,对任何答案都很高兴。对我来说这没有意义。我不在乎丢失信息。我只想连接所有以某种方式将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
答案 0 :(得分:2)
我猜你是真的试图从List<IScreen>
转换为List<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所说,如果你能提供更多详细信息(例如你得到的和你想要的东西),我们应该能够提供更多帮助。
答案 1 :(得分:1)
你没有提供很多细节。但是我们假设你有:
IRenderable {}
IScreen : IRenderable {}
private List<IRenderable> ConcatLists(IEnumerable<IRenderable> first, IEnumerable<IRenderable> second) { ... }
现在,您将无法在C#4之前的C#版本中直接使用IEnumerable&lt; IScreen&gt;调用ConcatLists方法。其原因称为共变和逆变。在框架4中,IEnumerable&lt; T&gt;声明为covariant,这意味着它可以隐式转换为IEnumerable,其中T是较小的类型(在您的情况下是IRenderable)。
如果你想在C#3中调用这样的方法,你可以使用扩展方法来帮助你。
这可能是:
ConcatLists(first.Cast<IRenderable>(), second);
如果声明“first”属于IRenderable类型。
答案 2 :(得分:1)
List<T0>
无法投放到List<T1>
。你应该为列表的每个元素进行强制转换。 IEnumarable的Cast扩展是这样做的:
List<IScreen> Screens = new List<IScreen>();
List<IRenderable> renderList = Screens.Cast<IRenderable>().ToList();