将通用列表传递给ObservableCollection构造函数

时间:2013-06-19 13:38:57

标签: c# generics .net-4.0 observablecollection

我确定我在这里遗漏了一些东西,但是这有什么特别的原因不起作用?

public ObservableCollection<object> ItemCollection { get; set; }

private void SetListData<T>(List<T> MyList)
{
    ItemCollection = new ObservableCollection<object>(MyList);
}

T这有什么价值吗?我认为对象的集合将覆盖每个案例,但似乎不是:

  

错误2参数1:无法转换   'System.Collections.Generic.List <T>'到   'System.Collections.Generic.List <object>'

更改属性的签名会导致一组全新的问题,因此将其更改为:

ItemCollection = new ObservableCollection<T>(MyList);

似乎不是一个好的解决方案。任何人都可以告诉我为什么我的原始代码不起作用,如果有任何简单的解决方法?

3 个答案:

答案 0 :(得分:6)

您有几个选择:

private void SetListData<T>(List<T> MyList) where T : class

ItemCollection = new ObservableCollection<object>(MyList.Cast<object>());

如果你有一个已知引用类型的List<T>,它可以工作,即使type参数不是object

var list = new List<string>();
var observable = new ObservableCollection<object>(list);

但在这种情况下,您使用的是泛型参数,该参数不是已知的引用类型;它可以是值类型/结构。这些可以“装箱”为object,但不是object s。

因此,您必须将该参数约束为始终为引用类型,或者允许任何类型T并在方法体内对object进行显式转换。

答案 1 :(得分:2)

你快到了。仅当List<T>是引用类型时,IEnumerable<object>才能转换为T(感谢协方差)。因此,将T限制为引用类型将起作用:

private void SetListData<T>(List<T> MyList) where T : class
{
    ItemCollection = new ObservableCollection<object>(MyList);
}

答案 2 :(得分:1)

问题是“T”不是“对象”,即使“T”继承“对象”。通用列表中的类型必须相同。

您最好的解决方案如下:

ItemCollection = new ObservableCollection<object>();
foreach(T item in MyList)
{
    ItemCollection.Add(item);
}