Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用具有接口的泛型集合_C#_Generics_Interface - Fatal编程技术网

C# 使用具有接口的泛型集合

C# 使用具有接口的泛型集合,c#,generics,interface,C#,Generics,Interface,我正在Windows 7上的Visual Studio 2013 Pro中使用C5/.NET 4.5 我希望使用项目集合,其中唯一的要求是项目实现特定的接口。集合中的项不一定是公共继承树的一部分,即集合不基于公共祖先,它们可以是任意类,但都将实现指定的接口,因此目标是将集合基于它们都实现的公共接口 我在这方面遇到了麻烦。如果我有一个实现所需接口的项集合,我无法将该集合传递给需要基于接口的集合的方法 这里有一些代码可以让它更具体 using System.Collections.Generic;

我正在Windows 7上的Visual Studio 2013 Pro中使用C5/.NET 4.5

我希望使用项目集合,其中唯一的要求是项目实现特定的接口。集合中的项不一定是公共继承树的一部分,即集合不基于公共祖先,它们可以是任意类,但都将实现指定的接口,因此目标是将集合基于它们都实现的公共接口

我在这方面遇到了麻烦。如果我有一个实现所需接口的项集合,我无法将该集合传递给需要基于接口的集合的方法

这里有一些代码可以让它更具体

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功能。