4

I have an ObservableCollection<DateTime> myItems

and it has some duplicate items that needs to be removed

I tried using :

myItems = myItems.Distinct();

however i can't build it and recieve this error:

Error 1 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.ObjectModel.ObservableCollection'. An explicit conversion exists (are you missing a cast?)

and when I check the ObservableCollection I find that it is IEnumerable<T> as the following Go to Definition shows:

public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged

public class Collection<T> : IList<T>, ICollection<T>, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

so I tried to cast as following :

myItems = (ObservableCollection<DateTime>) myItems.Distinct();

it build fine without error; but at runtime it throws the following error:

An exception of type 'System.InvalidCastException' occurred in mscorlib.ni.dll but was not handled in user code Additional information: Unable to cast object of type 'd__811[System.DateTime]' to type 'System.Collections.ObjectModel.ObservableCollection1[System.DateTime]'.

I also tried the following:

myItems = (ObservableCollection<DateTime>) myItems.Distinct().toList<DateTime>();

but then I reeive the following compile time error:

Error 1 Cannot convert type 'System.Collections.Generic.List' to 'System.Collections.ObjectModel.ObservableCollection'

what I am missing here? and how can I remove the duplicate items from the ObservableCollection ?

stackunderflow
  • 3,811
  • 5
  • 31
  • 43
  • 1
    Project a new Observable collection using the `IEnumerable` constructor: http://stackoverflow.com/q/3559821/314291 – StuartLC Jul 02 '14 at 08:29

2 Answers2

8

How about

myItems = new ObservableCollection<DateTime>(myItems.Distinct());
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
3

well you are missing the fact that, Distinct returns an IEnumerable<T>, which is not an ObservableCollection. And ToList returns a List<T> which is not an ObservableCollection either.

Those types are not convertible to ObservableCollection, so you can't cast them directly. You need to create a new ObservableCollection and populate it with new items.

You can do that using the constructor of ObservableCollection<T>, or you can also implement your own method (if you like to use fluent syntax of linq):

public static ObservableCollection<T> ToObservableCollection<T>(
       this IEnumerable<T> source)
{
     var collection = new ObservableCollection<T>();

     foreach(var item in source)
          collection.Add(item);

     return collection;
}
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • your explanation is great .. but i was fooled by the error message , it was misleading [ An explicit conversion exists (are you missing a cast?)].. so all my search was about the [missing cast] :( – stackunderflow Jul 02 '14 at 08:41
  • 1
    @stackunderflow if there is no implicit conversion defined between the types, than compiler will suggest you to cast it explicitly, if that isn't possible either then, it will throw `InvalidCastException` at runtime like in your example :) – Selman Genç Jul 02 '14 at 08:45