【问题标题】:IList<T> to ObservableCollection<T>IList<T> 到 ObservableCollection<T>
【发布时间】:2009-04-08 20:13:30
【问题描述】:

我在 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 作为参数的构造函数,所以我不能简单地新建一个。是否有一个看起来更像我缺少的选项 1 的替代方案,或者我只是在这里过于挑剔,而选项 2 确实是一个合理的选择。

另外,如果选项 2 是唯一真正的选项,是否有理由使用 IList 而不是 IEnuerable,如果我真正要做的只是遍历返回值并将其添加到其他类型收藏?

提前致谢

【问题讨论】:

  • silverlight 4 的更新:ObservableCollection 现在有一个将 IList 或 IEnumerable 作为参数的构造函数

标签: c# silverlight


【解决方案1】:

你可以编写一个快速而肮脏的扩展方法来让它变得简单

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();

【讨论】:

  • 我曾考虑过这一点,并且可能应该这么说。大多数情况下,我想确定我没有遗漏任何东西。
  • @Steve 不幸的是,我认为您没有忽略任何事情。
  • 向列表中添加新项目时不会出现问题。由于您创建了一个新的 ObservableCollection.,它将失去对该项目的跟踪
  • @azamsharp:确实如此。 1) To* 方法总是复制它们的输入 2) 因为源不提供 INotifyCollectionChanged ,所以无论如何都无法检测到对原始的更改。
  • Silverlight 4 现在有一个构造函数来“新建”一个 ObservableCollection - 所以你可以这样做而不是自己枚举。
【解决方案2】:

呃……

ObservableCollection 确实有一个constructor 将采用IEnumerable&lt;T&gt;,而IList&lt;T&gt; 派生自IEnumerable&lt;T&gt;

所以你可以“只是一个新的”

【讨论】:

  • 文档似乎不正确。我已经用 reflector.exe 验证了这一点
  • 这可能是 WPF 版本的 ObservableCollection 吗?我在 Silverlight 工作。编辑以将其包含在 TEXT 而不仅仅是标签中。
  • @JaredPar:你是说你使用反射器来验证 Silverlight 版本是否有 IEnumerable 构造函数?
  • @Steve Brouillard:我完全错过了 Silverlight 标签。我的错。我去找到了文档,其中不包括 IEnumerable 构造函数。
  • Silverlight 版本的文档,只有默认构造函数:msdn.microsoft.com/en-us/library/ms668604(VS.95).aspx
【解决方案3】:

JaredPar 为您提供的扩展方法是您在 Silverlight 中的最佳选择。它使您能够通过引用命名空间自动将任何 IEnumerable 转换为 observable 集合,并减少代码重复。与提供构造函数选项的 WPF 不同,没有内置任何内容。

ib.

【讨论】:

    【解决方案4】:

    不重新打开线程,但采用 IEnumerable 的 ObservableCollection 的构造函数已添加到 silverlight 4

    【讨论】:

      【解决方案5】:

      Silverlight 4 确实有能力只是 'new up' an ObservableCollection

      这是 Silverlight 4 中可能的缩短扩展方法。

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

      【讨论】:

        【解决方案6】:
                IList<string> list = new List<string>();
        
                ObservableCollection<string> observable = 
                    new ObservableCollection<string>(list.AsEnumerable<string>());
        

        【讨论】:

        • ObservableCollection 的 Silverlight 版本只有默认构造函数。不能新建一个并传递任何东西来初始化它。
        【解决方案7】:
        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
        

        【讨论】:

          【解决方案8】:

          你可以这样做:

          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);
               }
          }
          

          【讨论】:

            猜你喜欢
            • 2012-05-28
            • 2017-06-10
            • 1970-01-01
            • 2012-10-02
            • 2011-04-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多