C# 使用具有接口的泛型集合
我正在Windows 7上的Visual Studio 2013 Pro中使用C5/.NET 4.5 我希望使用项目集合,其中唯一的要求是项目实现特定的接口。集合中的项不一定是公共继承树的一部分,即集合不基于公共祖先,它们可以是任意类,但都将实现指定的接口,因此目标是将集合基于它们都实现的公共接口 我在这方面遇到了麻烦。如果我有一个实现所需接口的项集合,我无法将该集合传递给需要基于接口的集合的方法 这里有一些代码可以让它更具体C# 使用具有接口的泛型集合,c#,generics,interface,C#,Generics,Interface,我正在Windows 7上的Visual Studio 2013 Pro中使用C5/.NET 4.5 我希望使用项目集合,其中唯一的要求是项目实现特定的接口。集合中的项不一定是公共继承树的一部分,即集合不基于公共祖先,它们可以是任意类,但都将实现指定的接口,因此目标是将集合基于它们都实现的公共接口 我在这方面遇到了麻烦。如果我有一个实现所需接口的项集合,我无法将该集合传递给需要基于接口的集合的方法 这里有一些代码可以让它更具体 using System.Collections.Generic;
using System.Collections.Generic;
class Test
{
public interface IDrawable
{
void Draw();
}
public class Shape : IDrawable
{
public void Draw() {}
}
public void DrawItems(List<IDrawable> itemsToDraw) {}
public Test()
{
List<Shape> shapes = new List<Shape>();
DrawItems(shapes);
}
}
调用DrawItems会生成编译器错误。该方法需要一组实现IDrawable的项。我正在传递一组形状对象。因为形状对象确实实现了IDrawable,所以我希望我可以摆脱它
看起来这不管用,但我想知道为什么。我查阅了有关协方差和反方差的信息,但没有找到任何专门针对这种情况的信息
关于为什么这不起作用有什么想法或信息吗?这是一个非常常见的问题 正如你所注意到的,你想要的特征叫做协方差;在这个网站上搜索一下,你会发现很多类似的问题 列表不是协变的,因为它们不能安全地成为协变的。你有一碗苹果,你想把它当作一碗水果,但是你可以把香蕉放进一碗水果里,但是你不能把香蕉放进一碗苹果里。因此,你不能把一碗苹果当作一碗水果。这里也一样。形状列表不能用作可绘制对象的列表,因为可以将非形状放入可绘制对象的列表中 IEnumerable在C4中是协变的,如果T是引用类型,则更高。如果需要协方差,应该传递序列而不是列表。列表可以转换为IEnumerable,因为无法使用IEnumerable向列表中添加非形状 如果您想了解有关C中协方差和逆变换的更多信息,请参阅我的MSDN博客:
从底部开始;这些是按时间倒序排列的。谢谢!我搜索并找到了类似的解释,但我不清楚添加不兼容项的问题如何转化为无法传递集合。在阅读您的回复时,我想我假设的是只读特性,而实际上并不存在。但现在这是有道理的。谢谢你的链接,我去看看。@Nerdtron:不客气!这是我最喜欢的C4功能。