replace a simple forloop with linq
I want to know how to replace a simple foreach loop with linq. I'm not looking for answers about 2 or more loops....It's specifically for a single foreach loop..
List<string> strlist=new List<string>();
strlist.Add("Hello");
strlist.Add("World");
//The main "to be linq" here...
foreach(string str in strlist)
{
Console.Writeline(str);
}
开发者_Go百科
Now how do I write this simple loop in 1 line?
Thanks
The advice of Eric Lippert is not to write such loops as expressions.
Only use query expressions if the code does not have side-effects and produces a value.
In this case, you're looping to repeat a statement, which has a side-effect on the console and doesn't return values. So a foreach loop is clearer and is designed specifically for this purpose.
On the other hand, an action (which may have side-effects) can be regarded as a pure value before it is executed. So here's a list of numbers:
List<int> numbers = Enumerable.Range(1, 10).ToList();
From that we make a list of actions:
List<Action> actions = numbers.Select(n => Console.WriteLine(n)).ToList();
Although we're dealing with actions that have side effects, we aren't actually running them at all, so any further manipulations on the content of that list are not side-effecting. Then finally when we have the list we need, we can use a forloop to execute it:
foreach (var a in actions)
a();
And that is such a simple pattern, it could be argued that a RunAll
extension method on IEnumerable<Action>
would be no bad thing. Indeed, the .NET framework has this concept built into it: a multicast delegate is a single thing you can call which executes a bunch of delegates on a list. In the most common use cases (events), those delegates have side-effects.
You could use the ForEach method:
strlist.ForEach(x => Console.WriteLine(x));
As pointed out in the comments this works only for List<T>
. If your datasource is an IEnumerable<T>
you could write an extension method:
public static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> inputList, Action<T> action)
{
foreach (var item in inputList)
{
action(item);
}
}
}
You can use a ForEach
method (either on List<T>
or your own on IEnumerable<T>
) - but it's not very "idiomatically LINQ-y".
LINQ is based on functional principles - so the functions you provide are usually expected to be side-effect free. ForEach
is pointless if the function is side-effect free, so the two approaches are in tension.
Eric Lippert has a blog post providing more details.
Basically there's nothing wrong with using a foreach
when you want to do something with the data; LINQ is meant for querying the data. Typically you build up a LINQ query and then use a foreach
statement to use the data.
精彩评论