Kamil Budziewski
Kamil Budziewski

Reputation: 23087

C# Dynamic select List of strings

I'm trying to get List of strings from my dynamic object list and it keeps saying that:

Error 1 Cannot implicitly convert type 'System.Collections.Generic.List<dynamic>' to 'System.Collections.Generic.List<string>'

I'm selecting a property and use .ToString() on it:

var objects = new List<dynamic>();
//filling objects here

List<string> things = objects.Select(x => x.nameref.ToString()).ToList();

So isn't it a valid List of strings? Why compiler is assuming that this list is of type dynamic?

I've tried also converting from this answer, but it keeps giving me same error.

Anyone knows how to make it List<string>?

EDIT:

Why isn't it working? Because you can make mess like this:

public class Test
{
    public int ToString()
    {
        return 0;
    }
}

and compiler won't know if ToString returns string or int.

Upvotes: 19

Views: 7583

Answers (4)

Heinzi
Heinzi

Reputation: 172270

Although Rob's answer works fine, let me suggest an alternative: Cast nameref to the correct type (replace (object) by a more specific cast, if you happen to know the type of nameref):

List<string> things = objects.Select(x => ((object)x.nameref).ToString()).ToList();

The advantage of that solution is that ToString is statically resolved. Thus, the method call is

  • guaranteed to return string, since the compiler knows that you are calling Object.ToString() (or an overridden variant thereof) and

  • faster and cleaner. This solution keeps dynamic resolution to the absolute minimum needed (i.e., the resolution of x.nameref). Typos in the call to ToString are caught by the compiler.

(Of course, if the type of nameref happens to be string, you can just drop the call to ToString(), making your code even cleaner and shorter.)

Upvotes: 8

shree.pat18
shree.pat18

Reputation: 21757

You could try using Cast, like so:

List<string> things = objects.Select(x => x.nameref).Cast<string>().ToList();

You could also try casting in the Select itself:

List<string> things = objects.Select(x => x.nameref as string).ToList();

Upvotes: 6

Codor
Codor

Reputation: 17605

To my understanding, conversion to the desired List<string> can be done as follows.

var objects = new List<dynamic>();

// filling objects here

List<string> things = objects.Select(x => x.nameref.ToString()).Cast<string>.ToList();

Upvotes: 2

Rob
Rob

Reputation: 27357

You need to cast the items, like so:

List<string> things = objects.Select(x => x.nameref.ToString()).Cast<string>().ToList();

The reason why it's not recognizing that ToString() returns a string is that it's called on a dynamic object, and the method binding is done at runtime, not compile time.

Upvotes: 20

Related Questions