Katia
Katia

Reputation: 729

Can't call forAll on int[]

I'm reading Effective C# by Bill Wagner regarding query syntax and there is this example:

int[] foo = (from n in Enumerable.Range(0, 100)
                     select n * n).ToArray();
foo.ForAll((n) => Console.WriteLine(n.ToString()));

when testing it I get this error:

'int[]' does not contain a definition for 'ForAll' and no extension method 'ForAll' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)

I used the following directives:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

what else am I missing?
thanks in advance

update: testing on VS 2012 & .Net 4.5

both w.b and Ned Stoyanov answers work but not the example as it's in the book.
should I consider that just a wrong example?

I just noticed that AsParallel doesn't produce the expected result from the example.
Mentally running the example code it should print numbers from 0 to 99*99 in ascending order, while AsParallel prints the numbers but not the same order. So I guess AsParallel is not the exact answer, no?

Upvotes: 0

Views: 396

Answers (3)

NeddySpaghetti
NeddySpaghetti

Reputation: 13495

There is a ForAll in PLINQ, in which case your code should be:

foo.AsParallel().ForAll((n) => Console.WriteLine(n.ToString()));

Here is a link to the documentation. Note that AsParallel invokes the specified action for each entry in parallel and therefore not execute the lambda for each entry in the order of the entries in the enumerable.

Upvotes: 3

Grant Winney
Grant Winney

Reputation: 66439

You omitted some important text from between those two lines of code, and immediately after them.

Excerpted from "Effective C# (Covers C# 4.0): 50 Specific Ways to Improve Your C#" by Bill Wagner:

int[] foo = (from n in Enumerable.Range(0, 100)
            select n * n).ToArray();

You can then do a similar change to the second loop, although you'll also need to write an extension method to perform some action on all the elements:

foo.ForAll((n) => Console.WriteLine(n.ToString()));

The .NET BCL has a ForAll implementation in List<T>. It's juts as simple to create one for IEnumerable<T>:

public static class Extensions
{
    public static void ForAll<T>(
        this IEnumerable<T> sequence,
        Action<T> action)
    {
        foreach (T item in sequence)
            action(item);
    }
}

He created a ForAll extension method himself, so you'll need to copy that code too for your program to compile. It's just an extension method that uses foreach to loop over the elements in foo and perform the Console.WriteLine() action on each of them.

Upvotes: 3

w.b
w.b

Reputation: 11228

Change your data structure to List<int> and call ForEach on it:

List<int> foo = (from n in Enumerable.Range(0, 100)
                     select n * n).ToList();
foo.ForEach(n => Console.WriteLine(n.ToString()));

Upvotes: 1

Related Questions