问题描述:

I have the following code :

class Program

{

static void Main(string[] args)

{

Console.Write("By ForEach : ");

Enumerable.Range(0, 5).ToList().ForEach(i => { Console.Write(i); });

Console.WriteLine("");

Console.Write("By Select : ");

Enumerable.Range(0, 5).ToList().Select(i => { Console.Write(i); return i; });

Console.WriteLine("");

using (var sw = new StreamWriter("out.txt"))

{

sw.Write("By ForEach : ");

Enumerable.Range(0, 5).ToList().ForEach(i => { sw.Write(i); });

sw.WriteLine("");

sw.Write("By Select : ");

Enumerable.Range(0, 5).ToList().Select(i => { sw.Write(i); return i; });

sw.WriteLine("");

}

}

}

By running this, I got the result below in both Console and out.txt. :

By ForEach : 01234

By Select :

Points I want to know are:

  • Where the outputs of Console.Write and Streamwriter.Write went?
  • Is there general solution for this kind of problem?

网友答案:

Where the outputs of Console.Write and Streamwriter.Write went?

ForEach executes the delegate passed in immediately. .Select just creates a query whose execution is deferred until you actually iterate over it. You would see the output if you added a ToList at the end of the Select:

Enumerable.Range(0, 5).ToList().Select(i => { Console.Write(i); return i; }).ToList();

However - Linq is not meant to be used to execute code that has side-effects. The fact that you're having to call ToList just so you can call ForEach indicates that you are not using the right tool for what you want to do. If all you want to do is output the numbers just use a traditional foreach loop:

foreach(int i in Enumerable.Range(0, 5))
{
    Console.Write(i); 
}

Select is meant to take a collection and transform or project it to a new collection. It is not meant to replace traditional foreach loops where you want to perform some action based on the input.

相关阅读:
Top