【问题标题】:Cast an Explicit ObservableCollection强制转换 ObservableCollection
【发布时间】:2011-01-21 06:20:54
【问题描述】:

我在 C# 中有一个对象的 ObservableCollection。这个对象实现了一个接口。我希望能够将对象的 ObservableCollection 转换为接口的 ObservableCollection,而无需解析集合。

例如:

我有一个对象“Guitar”,它实现了一个名为“IMusicalInstrument”的接口。我将吉他对象的 ObservableCollection 绑定到 MyListBox。我希望以下代码行能够将列表框 itemsSource 转换为 ObservableCollection。

    ObservableCollection<IMusicalInstrument> InstrumentList = 
(ObservableCollection<IMusicalInstrument>)MyListBox.ItemsSource;

目前,这给了我一个 InvalidCastException。

有没有办法做到这一点(无需解析集合)?

谢谢, 赛斯

【问题讨论】:

    标签: c# data-structures casting observablecollection


    【解决方案1】:

    您不能转换它,但是一种方法是将您的迭代包装起来,我知道您想避免但不幸的是不能放入 extension method

    public static class CollectionExtensions
    {
        public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerableList)
        {
            if (enumerableList != null)
            {
                //create an emtpy observable collection object
                var observableCollection = new ObservableCollection<T>();
    
                //loop through all the records and add to observable collection object
                foreach (var item in enumerableList)
                    observableCollection.Add(item);
    
                //return the populated observable collection
                return observableCollection;
            }
            return null;
        }
    }
    

    这将允许您执行类似...

    ObservableCollection<IMusicalInstrument> InstrumentList = MyListBox.ItemsSource.ToObservableCollection<IMusicalInstrument>();
    

    ...这就是我相信你所追求的。

    您也可以简单地将IEnumerable&lt;T&gt; 引用传递给ObservableCollection&lt;T&gt; 的构造函数...

    ObservableCollection<IMusicalInstrument> InstrumentList = new ObservableCollection<IMusicalInstrument>(MyListBox.ItemsSource);
    

    【讨论】:

    • ObservableCollection 已经有一个可以执行此操作的构造函数。
    • 这当然不提供来自源的通知,只是一个新的 observable 集合,其中原始作为项目的源。
    • @Steve To... 一般会返回一个新实例; ToListToArray 等等。一旦您开始使用新实例,新返回的ObservableCollection 显然会提供伴随该类型的所有通知。如果您打算继续使用支持IEnumerable,那将按预期进行。
    • 确实 - 我只是从他想要一种“管道”的问题中得到印象,其中集合中项目的类型发生了变化,但继续提供通知。我以前有过这样的要求(这就是我最终来到这里的原因:))。
    【解决方案2】:

    除非MyListBox.ItemsSourceObservableCollection&lt;IMusicalInstrument&gt; 的实例,否则不,你不能转换它。

    【讨论】:

      【解决方案3】:

      抱歉,您不能这样做,因为 ObservableCollection&lt;Guitar&gt; 不能被视为 ObservableCollection&lt;IMusicalInstrument&gt; - 例如你不能打电话给collection.Add(new Flute())

      【讨论】:

        【解决方案4】:

        如果您只想管理集合中的项目,那么您可以尝试将 ItemsSource 转换为非泛型 IList。

        【讨论】:

          【解决方案5】:

          如果您只是使用 ObservableCollection 来处理集合更改事件,您可以强制转换为 INotifyCollectionChanged 并添加您的事件处理程序。 INotifyCollectionChanged 不使用泛型,因此无论如何您都必须在事件处理程序中进行强制转换。

          但是,如果您想枚举您的 IMusicalInstrument 实例集合,您可以使用 Linq Cast() 扩展方法。例如

          IEnumerable<IMusicalInstrument> instruments = 
               ((IEnumerable)MyListBox.ItemsSource).Cast<IMusicalInstrument>();
          

          希望有帮助!

          【讨论】:

            猜你喜欢
            • 2010-12-24
            • 2021-05-28
            • 2012-02-10
            • 1970-01-01
            • 2011-10-12
            • 2017-10-31
            • 1970-01-01
            • 2010-10-16
            • 2021-01-24
            相关资源
            最近更新 更多