Craig Otis
Craig Otis

Reputation: 32094

Using the Select() Method on a List

I'm using a ListView to display a collection of items, and I'm assigning those items like so:

page.Items = _sampleData.Cats.Select(obj => (object) obj);

This works great, each Cat is displayed in the list. Reproducibly, if I remove the (object) cast, and assign the Items using

page.Items = _sampleData.Cats.Select(obj => obj);

or

page.Items = _sampleData.Cats;

Then instead of the data being stored properly, the children of the first Cat are instead displayed in the list. This seems... not intuitive? Is there some edge case I'm hitting in my code that is performing differently if the Items are not explicitly objects, or does that cast really make a difference?

Edit: Additional code.

Cats is a List of Cat objects:

public class Cat : IEnumerable<Trait>, IEnumerable
{
    public String Name;
    // getter and setter

    public List<Trait> Traits;
    // getter and setter

    public IEnumerator<Trait> GetEnumerator() {
        return Traits.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

The ListView is a Metro UI component:

<ListView x:Name="CatListView" ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" ...>

And the data is being provided to the ListView though a setter for Items in one of my classes:

private IEnumerable<object> _items;
public IEnumerable<object> Items
{
    get
    {
        return _items;
    }

    set
    {
        _items = value;
        CollectionViewSource.Source = value;
    }
}

Upvotes: 1

Views: 296

Answers (1)

wsanville
wsanville

Reputation: 37516

A simpler way to accomplish what you're doing is to use Cast<>():

page.Items = _sampleData.Cats.Cast<object>();

(Original answer below, which is not so valid after all given the comments.)

This is because you can not assign a collection of a derived class to a collection of a base class.

Let's take LINQ out of the equation. page.Items is of type List<object>. Suppose the following would compile (it doesn't):

page.Items = _sampleData.Cats;

Then, note it's perfectly valid to put anything that inherits from object into a List<object>. But, in this case, our list of objects is really a list of Cat.

So, attempting the following would logically work out, because it appears that you're adding a Banana to a list of object, but the list is really a list of Cats.

var b = new Banana();
page.Items.Add(b);

You can't put a Banana in a List<Cat>.

Upvotes: 3

Related Questions