ObservaleCollection <myclass>与IEnumerable <imyinterface>不一样?</imyinterface> </myclass>

时间:2010-02-23 13:53:33

标签: c#

我有一个界面:

public interface IMyInterface { }

我有一个实现接口的类:

public class MyClass : IMyInterface { }

我有一个函数要求IEnumerable的IMyInterface:

private void TestFunction(IEnumerable<IMyInterface> collectie) { }

我无法弄清楚为什么这不起作用:

ObservableCollection<MyClass> myClasses = new ObservableCollection<MyClass>();
TestFunction(myClasses); // this line doesn't work

ObservableCollection是IEnumerable,对吗?

我的班级确实实施了,对吧?

那么为什么这不起作用?

它给出了这2个错误:

  

错误1最佳重载方法   匹配   'WindowsFormsApplication1.Form1.TestFunction(System.Collections.Generic.IEnumerable)'   有一些无效的   参数C:\ spike \ spike_rtf \ WindowsFormsApplication1 \ Form1.cs 59 4 WindowsFormsApplication1   错误2参数'1':无法转换   从   'System.Collections.ObjectModel.ObservableCollection'   至   'System.Collections.Generic.IEnumerable'C:\ spike \ spike_rtf \ WindowsFormsApplication1 \ Form1.cs 59 17 WindowsFormsApplication1

3 个答案:

答案 0 :(得分:8)

您在通用差异之后。这将在.NET 4.0和C#4.0中受支持,仅适用于接口和委托(并且仅在适当的情况下)。这对你的情况没问题,因为你对IEnumerable<T>接口感兴趣,它在.NET中变成IEnumerable<out T>来表示它的协方差。

在.NET 3.5中执行此操作的最简单方法可能是使用Cast<>

TestFunction(myClasses.Cast<IMyInterface>());

(这就像用户友好的“选择”建议,但有点简单。如果不能在C#4中工作的情况也值得了解 - 如果你碰巧知道集合中的每个项目都是正确的类型,但你不能在类型系统中表达它。)

要了解更多相关信息,请参阅Eric Lippert关于该主题的blog posts。为你的思想融化做好准备 - 我知道当我考虑差异太大时我会这样做。 Eric也在Stack Overflow上就此主题撰写了各种答案,包括评论中提出的this one

答案 1 :(得分:2)

.NET 4.0将支持此“功能” http://msdn.microsoft.com/en-us/library/dd799517(VS.100).aspx

使用LINQ从ObservableCollection转换为ObservableCollection:

var converted = myClassCollection.Select(o=>(IMyInterface)o).ToIEnumerable();

答案 2 :(得分:1)

它是.NET中泛型的众所周知的局限性。这是一个非常酷的技术术语,我现在还不太清楚。

修改:通用差异。该死的,Skeet!

您可以使用Linq扩展方法Cast执行此操作:

class Program
{
    static void Main(string[] args)
    {
        var original = new List<Bar>();
        IEnumerable<IFoo> foos = original.Cast<IFoo>();
    }
}

public interface IFoo { }
public class Bar : IFoo { }