34

I have a List<int> and I want to convert it to a List<double>. Is there any way to do this other than just looping through the List<int> and adding to a new List<double> like so:

List<int> lstInt = new List<int>(new int[] {1,2,3});
List<double> lstDouble = new List<double>(lstInt.Count);//Either Count or Length, I don't remember

for (int i = 0; i < lstInt.Count; i++)
{
    lstDouble.Add(Convert.ToDouble(lstInt[0]));
}

Is there a fancy way to do this? I'm using C# 4.0, so the answer may take advantage of the new language features.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
Ames
  • 625
  • 1
  • 7
  • 10
  • 1
    (for the record, note that the C# 4.0 variance won't work on concrete-types (`List`), won't work on lists generally (`IList`), and won't work between `int` and `double`) – Marc Gravell Jan 18 '10 at 07:49

6 Answers6

63

You can use Select as suggested by others, but you can also use ConvertAll:

List<double> doubleList = intList.ConvertAll(x => (double)x);

This has two advantages:

  • It doesn't require LINQ, so if you're using .NET 2.0 and don't want to use LINQBridge, you can still use it.
  • It's more efficient: the ToList method doesn't know the size of the result of Select, so it may need to reallocate buffers as it goes. ConvertAll knows the source and destination size, so it can do it all in one go. It can also do so without the abstraction of iterators.

The disadvantages:

  • It only works with List<T> and arrays. If you get a plain IEnumerable<T> you'll have to use Select and ToList.
  • If you're using LINQ heavily in your project, it may be more consistent to keep using it here as well.
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
42

You can use LINQ methods:

List<double> doubles = integers.Select<int, double>(i => i).ToList();

or:

List<double> doubles = integers.Select(i => (double)i).ToList();

Also, the list class has a ForEach method:

List<double> doubles = new List<double>(integers.Count);
integers.ForEach(i => doubles.Add(i));
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • This needs to be Select(i => i).ToList(); Is there a way to use the <,> syntax with a 'Type' variable instead of int? – Ames Jan 18 '10 at 07:42
  • 1
    @Chris: It would actually normally just be `integers.Select(i => (double)i)` to be idiomatic. But no, generics are a compile-time feature - if you want to use a type only known at execution time, you'll need to use reflection. Dynamic typing in C# 4 may be able to help you with that, but you'd have to give a more concrete example before we could say for sure. – Jon Skeet Jan 18 '10 at 07:44
  • Using the second demo, I can create a reflection list of type double, then use the foreach stuff to add items from the int based list. Promotion will occur and everything happy will happen. This response actually solved my problem, but the ones above are more concise to the question I asked. – Ames Jan 18 '10 at 07:48
8

You could do this using the Select extension method:

List<double> doubleList = intList.Select(x => (double)x).ToList();
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • So is there any point in not just using a loop? Performance wise? – Ames Jan 18 '10 at 07:44
  • @Chris: Using Select and ToList won't be more efficient. ConvertAll *might* be - you lose the overhead of the checks within Add, but there's the overhead of calling a delegate that many times. Do you have evidence that this code is a bottleneck for you? – Jon Skeet Jan 18 '10 at 07:47
  • No evidence at all. In my application the "double" example will be dynamic so casting is difficult to do without reflection. I was just wondering if there was some neat lamba function or something that I didn't know about that took care of casting so to speak. – Ames Jan 18 '10 at 07:52
  • @Chris: You could build an expression tree to perform the conversion, quite possibly. However, at that point you've got a somewhat different question. – Jon Skeet Jan 18 '10 at 07:59
  • I can just use reflection. I've got my problem solved. I ended just doing a foreach and adding to a dynamic reflection generated list of . Thanks for the help. – Ames Jan 18 '10 at 09:13
2

You can use ConvertAll method inside of .Net Framework 2.0 here is an example

        List<int> lstInt = new List<int>(new int[] { 1, 2, 3 });
        List<double> lstDouble = lstInt.ConvertAll<double>(delegate(int p)
        {
            return (double)p;
        });
fyasar
  • 3,996
  • 2
  • 42
  • 55
2

You can use a method group:

lstDouble = lstInt.Select(Convert.ToDouble)
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Tom
  • 21
  • 1
0

You can use Select or ConvertAll. Keep in mind that ConvertAll is available in .Net 2.0 too

Giorgi
  • 30,270
  • 13
  • 89
  • 125