2

I have a list of objects that implement the .ToString() method. I was expecting to find a really easy to to call the .ToString() method for each item in the list, and get a list of strings.

Here is a way to do it in a foreach.

List<string> entityNames = new List<string>();
foreach (Entity parent in parents)
{
    entityNames.Add(parent.ToString());
}

This is the best I came up with, is there a better way?

IList<string> entityNames2 = (from parent in parents where true select user.ToString()).ToList();
Miebster
  • 2,365
  • 4
  • 21
  • 27
  • Side note: "the best" without describing what "better" means for you is generally sign of bad question. Based on accepted answer you were looking for "shorter is better" solutions - see my comment to accepted answer to get a bit more from it. – Alexei Levenkov Sep 28 '14 at 00:57

2 Answers2

9

List has a ConvertAll() method that does exactly what you want.

To generate a new list from an existing list, you would do

List<string> entityNames = parents.ConvertAll(p => p.ToString());

Note that parents has to be a list for this to work, the method is not defined for IEnumerables.

For IEnumerables, you could also use a normal select() and then call ToList() afterwards:

parents.Select(p=>p.ToString()).ToList();

(This is equivalent to the line you came up with in query syntax, but using linq method syntax)

This is a little less efficient than ConvertAll(), in the first case a new list of the correct size is allocated once, in the second case the correct size is not known beforehand, so the new list needs to grow dynamically. In most cases this difference is most likely insignificant, and the second method works for all IEnumerables, not just lists

HugoRune
  • 13,157
  • 7
  • 69
  • 144
  • +1. Since OP likely looking for the the best by size you can drop `p=>p.` part from `Select`: `.Select(ToString)` would be 5 characters shorter. – Alexei Levenkov Sep 28 '14 at 00:56
  • 1
    @Alexei, I don't think this will work: while you can just pass a method with the correct signature to select instead of constructing a new method via lambda syntax, in this case, if you call `x.Select(ToString)` the compiler will attempt to use the ToString() of the class of the current method, not the ToString() of the elements in x, and both have the wrong signature (not Func) – HugoRune Sep 28 '14 at 01:22
  • HugoRune, indeed you are right... Actually it even fails to compile - not sure what I was thinking. `Convert.ToString` would work, but it is 3 characters longer: `parents.Select(Convert.ToString).ToList()`. – Alexei Levenkov Sep 28 '14 at 01:31
0

There are two ways that come to mind:

entityNames = parents.Select(p => p.ToString()).ToList();

or

entityNames = parents.Cast<string>().ToList();

This SO question and this one have more information on the difference between the Select() and Cast() methods.

See Enumerable.Select - MSDN and Enumerable.Cast Method - MSDN for more information.

Community
  • 1
  • 1
jordanhill123
  • 4,142
  • 2
  • 31
  • 40