简体   繁体   English

强制转换为ObservableCollection

[英]Cast an Explicit ObservableCollection

I have an ObservableCollection of an object in C#. 我在C#中有一个对象的ObservableCollection。 This object implements an interface. 该对象实现一个接口。 I would like to be able to convert the ObservableCollection of the object to an ObservableCollection of the interface without having to parse through the collection. 我希望能够将对象的ObservableCollection转换为接口的ObservableCollection,而不必解析整个集合。

So for example: 因此,例如:

I have an object "Guitar" which implements an interface called "IMusicalInstrument". 我有一个对象“ Guitar”,该对象实现了一个称为“ IMusicalInstrument”的接口。 I bind an ObservableCollection of Guitar objects to MyListBox. 我将吉他对象的ObservableCollection绑定到MyListBox。 I want the following line of code to be able to convert listbox itemsSource to an ObservableCollection. 我希望下面的代码行能够将列表框itemsSource转换为ObservableCollection。

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

Currently, that is giving me an InvalidCastException. 当前,这给了我一个InvalidCastException。

Is there a way to accomplish this (without having to parse through the collection)? 有没有办法做到这一点(而不必解析整个集合)?

Thanks, Seth 谢谢,赛斯

You can not cast it however one approach is to wrap your iteration which I know you want to avoid but unfortunately can't into an 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;
    }
}

This would allow you to do something like... 这将允许您执行类似...

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

...which is what I believe you are after. ...这就是我所追求的。

You can also simply pass the IEnumerable<T> reference into the constructor of ObservableCollection<T> ... 您还可以简单地将IEnumerable<T>引用传递到ObservableCollection<T>的构造函数中...

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

除非MyListBox.ItemsSourceObservableCollection<IMusicalInstrument>的实例,否则否,您不能进行ObservableCollection<IMusicalInstrument>

抱歉,您不能执行此操作,因为ObservableCollection<Guitar>不能被视为ObservableCollection<IMusicalInstrument> -例如,您不能在其上调用collection.Add(new Flute())

如果只想管理集合中的项目,则可以尝试将ItemsSource强制转换为非通用IList。

If you are using ObservableCollection simply to handle collection changed events, you could cast to INotifyCollectionChanged and add your event handler. 如果仅使用ObservableCollection来处理集合更改的事件,则可以强制转换为INotifyCollectionChanged并添加事件处理程序。 The INotifyCollectionChanged does not use generics, so you would have to cast in your event handler anyhow. INotifyCollectionChanged不使用泛型,因此无论如何您都必须强制转换事件处理程序。

However, if you want to enumerate your collection of IMusicalInstrument instances, you can use the Linq Cast() extension method. 但是,如果要枚举IMusicalInstrument实例的集合,则可以使用Linq Cast()扩展方法。 eg 例如

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

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM