tags:

views:

66

answers:

3

Hello everyone, 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);
}

Now how do I write this simple loop in 1 line?

Thanks

+5  A: 

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);
        }
    }
}
Darin Dimitrov
Just pointing out that only works with List<T> (which is the case in the question posed), while LINQ stuff generally works with IEnumerable<T>.
Martinho Fernandes
Yes, but as there's no equivalent for `IEnumerable<T>` it should be pretty trivial to implement an extension method for this.
Darin Dimitrov
+5  A: 

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.

Daniel Earwicker
+3  A: 

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.

Jon Skeet