pgee70
pgee70

Reputation: 4004

optimise code into linq expression

I have an observable collection I want to remove an element from. I have tried using the linq .Where syntax but i am getting stuck with the casting.

public class Atc
{
    public string Code { get; set; }
    public string Description { get; set; }
    public string ParentDescriptions { get; set; }
}

i have defined the observable collection of medicines,

public ObservableCollection<Atc> MedicinesObservableCollection

and i have a method to filter out the item from the collection that works:

private void RemoveMedicineListItem(string code)
{
    var filteredCollection = new ObservableCollection<Atc>();
    foreach (var item in MedicinesObservableCollection)
    {
        if (item.Code != code)
        {
            filteredCollection.Add(item);
        }
    }
    MedicinesObservableCollection = filteredCollection; 
}

I have tried:

(ObservableCollection<Atc>)MedicinesObservableCollection.Where(x => x.Code != code);

but this gets a runtime exception System.InvalidCastException: 'Unable to cast object of type 'WhereEnumerableIterator1[Atc]' to type 'System.Collections.ObjectModel.ObservableCollection1[Atc]'.'

i get this is something to do with the linq enumerables but i am out of my depth.

Upvotes: 0

Views: 68

Answers (3)

Filip Cordas
Filip Cordas

Reputation: 2561

All the answers are correct but when using ObservableCollection it would be better to do a remove on the same object rather then creating a new list.

MedicinesObservableCollection.Remove(MedicinesObservableCollection.FirstOrDefault(x => x.Code == code));

This is because recreating the collection might force all the items in the list to be re-rendered and this way only one item will be removed from the same collection.

Upvotes: 3

Joe
Joe

Reputation: 7004

Linq doesn't return a collection of the same type as the input. See this. So your cast to ObservableCollection<Atc> fails as it's some internal implementation of IEnumerable, not an ObservableCollection.

The solution is just to create a new ObservableCollection:

var items = new ObservableCollection<Atc>(MedicinesObservableCollection.Where(x => x.Code != code));

Upvotes: 1

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37020

You can´t cast an instance of WhereIterator<Atc> (which your Where-clause actually returns) to ObservableCollection<Atc>). The returned instance only implements IEnumerable<Atc>, this is you can iterate it. However it doesn´t havy anything in common with any list, or in particular with an observable one.

However you can create a new one based on the returned value:

var result = new ObservableCollection(MedicinesObservableCollection.Where(x => x.Code != code));

Upvotes: 4

Related Questions