将IList<T>转换为ObservableCollection<T>。

17

我有一个在Silverlight应用程序中的方法,目前返回的是IList类型,我想找到最干净的方式将其转换为ObservableCollection类型:

public IList<SomeType> GetIlist()
{
   //Process some stuff and return an IList<SomeType>;
}

public void ConsumeIlist()
{
   //SomeCollection is defined in the class as an ObservableCollection

   //Option 1
   //Doesn't work - SomeCollection is NULL 
   SomeCollection = GetIlist() as ObservableCollection

   //Option 2
   //Works, but feels less clean than a variation of the above
   IList<SomeType> myList = GetIlist
   foreach (SomeType currentItem in myList)
   {
      SomeCollection.Add(currentEntry);
   }
}

ObservableCollection没有一个可以接受IList或IEnumerable作为参数的构造函数,所以我不能简单地使用new来创建一个。是否有一个更像选项1的替代方案我错过了,还是我在这里太挑剔了,选项2确实是一个合理的选择。
另外,如果选项2是唯一的真正选择,那么如果我只是迭代返回值并将其添加到某种其他集合中,是否有理由使用IList而不是IEnurerable?
提前致谢。

2
Silverlight 4 的更新:ObservableCollection 现在有一个构造函数,可以接受 IList 或 IEnumerable 作为参数。 - Simon_Weaver
8个回答

33
你可以编写一个简单而不完善的扩展方法,使其更加方便。
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerable) {
  var col = new ObservableCollection<T>();
  foreach ( var cur in enumerable ) {
    col.Add(cur);
  }
  return col;
}
现在你可以直接编写。
return GetIlist().ToObservableCollection();

2
我曾经考虑过这个问题,也许应该这么说。主要是想确保我没有错过任何内置的东西。 - Steve Brouillard
1
@Steve,不幸的是,我认为你没有忽略任何事情。 - JaredPar
当您向列表中添加新项时,这不会引起问题吗?由于您创建了一个新的ObservableCollection<T>,它将无法跟踪该项。 - azamsharp
@azamsharp:确实。1)To*方法总是复制它们的输入2)由于源不提供INotifyCollectionChanged,因此无论如何都无法检测到对原始内容的更改。 - David Schmitt
Silverlight 4现在有一个构造函数可以“new up”一个ObservableCollection<T> - 所以你可以直接这样做,而不必自己枚举。 - Simon_Weaver

21

文档似乎是错误的。我已经用 reflector.exe 进行了验证。 - JaredPar
这可能是ObservableCollection的WPF版本吗?我正在使用Silverlight。编辑以包括在TEXT中而不仅仅是标签中。 - Steve Brouillard
@JaredPar:你是说你使用了反射器来验证Silverlight版本是否有IEnumerable构造函数? - Randolpho
@Steve Brouillard:我完全错过了Silverlight标签,我的错。我去找了文档,发现其中并没有包括IEnumerable构造函数。 - Randolpho
我确实有一个List<T>构造函数,他可能会混淆。但最终在这里不相关。 - Steve Brouillard
显示剩余6条评论

2

Silverlight 4可以通过“新建”ObservableCollection来实现。

下面是在Silverlight 4中可能出现的简短扩展方法。

public static class CollectionUtils
{
    public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> items)
    {
        return new ObservableCollection<T>(items);
    }
}

2

不是为了重新打开这个线程,而是在Silverlight 4中添加了一个接受IEnumerable的ObservableCollection构造函数。


2

JaredPar给你的扩展方法是Silverlight中最好的选择。只需引用命名空间,它就可以自动将任何IEnumerable转换为可观察集合,并减少代码重复。与WPF不同,Silverlight没有内置构造函数选项。

ib.


1
        IList<string> list = new List<string>();

        ObservableCollection<string> observable = 
            new ObservableCollection<string>(list.AsEnumerable<string>());

Silverlight版本的ObservableCollection只有默认构造函数。无法创建新的实例并传递任何内容来初始化它。 - Steve Brouillard

1
Dim taskList As ObservableCollection(Of v2_Customer) = New ObservableCollection(Of v2_Customer)
' Dim custID As Guid = (CType(V2_CustomerDataGrid.SelectedItem,  _
'         v2_Customer)).Cust_UUID
' Generate some task data and add it to the task list.
For index = 1 To 14
    taskList.Add(New v2_Customer() With _
                 {.Cust_UUID = custID, .Company_UUID, .City
                 })
Next

Dim taskListView As New PagedCollectionView(taskList)
Me.CustomerDataForm1.ItemsSource = taskListView

0
你可以这样做:
public class SomeTypeCollection: ObservableCollection<SomeType>
{
    public SomeTypeCollection() : base() { }
    public SomeTypeCollection(IEnumerable<SomeType> IEObj) : base(IEObj) { 
 }
}

public ConsumeIlist
{
    public SomeTypeCollection OSomeTypeCllt { get; set; }
    MyDbContext _dbCntx = new MyDbContext();
     public ConsumeIlist(){
          OSomeTypeCllt = new 
   SomeTypeCollection(_dbCntx.ComeTypeSQLTable);
     }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接