Johannes Schacht
Johannes Schacht

Reputation: 1344

Casting Linq results does not work as expected

This could be a stupid question as I'm pretty new to Linq. I've created a Linq expression that returns a list of strings. I can iterate over the result. However when I cast the result to a List it produces a run time error. See this code:

class Product { public string name; }

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, Product> p1 = new Dictionary<string, Product>();
        p1["a"] = new Product() { name = "first"} ;
        p1["b"] = new Product() { name = "second" };

        var Y = p1.Values.Select(x => x.name);
        foreach (string s in Y) { Console.WriteLine(s); }

        List<string> ls = (List<string>)p1.Values.Select(x => x.name); // this fails !?
        Console.Read();
    }
}

Upvotes: 0

Views: 202

Answers (5)

walther
walther

Reputation: 13600

List<string> ls = p1.Values.Select(x => x.name).ToList();

is usually the correct way to do this. Linq methods (e.g. Select) return IEnumerable, so you can't cast it this way. IEnumerable is a very general collection, while List is concrete. You can't safely assume that every IEnumerable is List, but you can say that every List is also IEnumerable...

In the MSDN documentation you can see, that such explicit castings fail, if the cast type isn't in fact of the same type as the target type. See this to get a better idea about casting http://msdn.microsoft.com/en-us/library/ms173105.aspx

Or you can do it like this:

var results = 1.Values.Select(x => x.name);
List<string> ls = new List<string>(results); 

by using the overload constructor that accepts IEnumerable, but ToList() is much more common in situations like this.

Upvotes: 4

Ed Swangren
Ed Swangren

Reputation: 124692

p1.Values.Select(x => x.name); // this fails !?

Yes, it does, because Select does not return a List<string> hidden behind the IEnumerable<T> interface. Use ToList().

var ls = p1.Values.Select(x => x.name).ToList();

Upvotes: 4

Mark PM
Mark PM

Reputation: 2919

Linq returns an IEnumerable<string> in that case which is not a List<string>, you can tell Linq to convert it to string by using the .ToList() at the end of the expression:

List<string> ls = p1.Values.Select(x => x.name).ToList();

Upvotes: 1

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101701

It fails because Select does not return a List. you need to use ToList to materialize your query:

 List<string> ls = p1.Values.Select(x => x.name).ToList();

LINQ methods uses deferred execution, it means they don't return you results until you run the query by iterating (e.g using foreach) or use some method to force iteration (like ToArray or ToList method).

Here are some useful readings:

Upvotes: 8

Daniel A. White
Daniel A. White

Reputation: 190942

Use the .ToList() extension method. It is not a list at that point, but an IEnumerable<string>.

Upvotes: 1

Related Questions