代码之家  ›  专栏  ›  技术社区  ›  Natrium

ObservableCollection<myClass>与IEnumerable<imyinterface>不同?

c#
  •  2
  • Natrium  · 技术社区  · 15 年前

    我有一个接口:

    public interface IMyInterface { }
    

    我有一个实现接口的类:

    public class MyClass : IMyInterface { }
    

    我有一个函数,它要求一个IMYInterface的IEnumerable:

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

    我不明白为什么这样不行:

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

    ObservableCollection是一个IEnumerable,对吧?

    我的课也会实现,对吗?

    为什么这个不管用?

    它给出两个错误:

    错误1最佳重载方法 匹配 'WindowsFormsApplication1.Form1.TestFunction(System.Collections.Generic.IEnumerable)' 有一些无效的 参数C:\Spike\Spike\RTF\WindowsFormsApplication1\Form1.cs 59 4 WindowsFormsApplication1 错误2参数“1”:无法转换 从 '系统.collections.objectmodel.observablecollection' 到 'System.Collections.Generic.IEnumerable'C:\Spike\Spike\RTF\WindowsFormsApplication1\Form1.cs 59 17 WindowsFormsApplication1

    3 回复  |  直到 15 年前
        1
  •  8
  •   Community CDub    8 年前

    你在追求 一般方差 .这将在.NET 4.0和C 4.0中得到支持,仅适用于接口和委托(并且仅适用于适当的情况)。不过,这对你的案子没关系,因为你对 IEnumerable<T> 界面 IEnumerable<out T> 在.NET中表示它的协方差。

    在.NET 3.5中,最简单的方法是使用 Cast<> 以下内容:

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

    (这类似于用户友好的“选择”建议,但有点简单。对于那些 不会 在C 4工作-如果你 碰巧知道 集合中的每个项都将是正确的类型,但不能在类型系统中表示。)

    要了解更多信息,请参阅Eric Lippert的 blog posts 关于这个话题。准备好让你的思想融化-我知道当我认为方差太难的时候我的会融化。 Eric 在堆栈溢出上也写了关于这个主题的各种答案,包括 this one 在评论中建议。

        2
  •  2
  •   User Friendly    15 年前

    .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();
    
        3
  •  1
  •   Will    15 年前

    它是.NET中常见的泛型限制。有一个非常酷的技术术语,我现在记不清了。

    编辑 :一般方差。该死的,双向飞碟!

    可以使用LINQ扩展方法强制转换来执行此操作:

    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 { }