r0n9
r0n9

Reputation: 2729

C# extension of Enumerable not working

I am trying to add an extension to Enumerable class. but it seems that the extension FindEven() is not picked by the C# compiler. When I build, the compiler spit error :

CS0117 'Enumerable' does not contain a definition for 'FindEven'

Here is my code:

namespace ConsoleApp1
{
  static public class Program
  {
    static IEnumerable<int> FindEven(this IEnumerable<int> array, Func<int, bool> predicte)
    {
      foreach (var n in array)
      {
        if (predicte(n))
        {
          yield return n;
        }
      }
    }
    static public void Main(string[] args)
    {
      int[] numbers = new[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

      var result = Enumerable.Select(Enumerable.FindEven(numbers, n => n % 2 == 0), n => n);
      foreach (var output in result)
        Console.WriteLine(output);

      Console.ReadLine();
    }
  }
}

Anything I did incorrectly here?

[edit]

What I am trying to do here is to see how the 'where' statement in the following LINQ works by making my own version of 'Where', which in this case is 'FindEven' (not a good name I have to admit).

var result = from element in numbers
where element % 2 == 0
select element;

I think if I replace 'FindEven' by 'Where' which is defined in Enumerable[from metadata]... It should be the way LINQ works. But I just can not get the code compiled.

Thanks

Upvotes: 0

Views: 872

Answers (3)

Sarvesh Mishra
Sarvesh Mishra

Reputation: 2072

As per your edit, you can use Where function.

namespace ConsoleApp1
{
    static public class Program
    {
        static public void Main(string[] args)
        {
            int[] numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var result = numbers.Where(n => n % 2 == 0);
            foreach (var output in result)
                Console.WriteLine(output);

            Console.ReadLine();
        }
    }
}

Upvotes: 1

Avner Shahar-Kashtan
Avner Shahar-Kashtan

Reputation: 14700

Per your edit, it seems you're trying to add your FindEven function to the Enumerable class, but that won't work. When you're calling Enumerable.Where, you're not calling an extension method, you're calling an actual static method that's defined in Enumerable. You can't extend that class that way, because extension methods can't extend static methods, that's not what they're for. They extend instance methods.

The equivalent in your code of calling Enumerable.Where is calling Program.FindEven. That's where the static method is defined. The magic of extension methods is having both Where and FindEven available for an instance of IEnumerable<int>, regardless of where they're defined.

Pre-edit

From the way you call the method, you seem to believe that the extension method adds a new static method to the Enumerable class. It doesn't work that way. The extension method you defined will "add" the method to any instance of IEnumerable<int>, so your code will look like this:

var result = numbers.FindEven(n => n % 2 == 0);

Note, though, that your FindEven doesn't actually FindEven - it just queries using the provided predicate, meaning it's exactly the same as the built-in LINQ Where function. A proper FindEven method would be:

static IEnumerable<int> FindEven(this IEnumerable<int> source)
{
    return source.Where(n => n % 2 == 0);
}

This will return a lazily-evaluated IEnumerable<int> containing only the even numbers.

Also, your external Select method does nothing - it just maps every integer to itself, meaning it returns an enumerable that's completely equivalent to its input.

Upvotes: 6

Gian Paolo
Gian Paolo

Reputation: 4249

When you define an extension method, you have to call it as it was a member function of your this IEnumerable<int> array parameter

simply replace your call with

var result = Enumerable.Select(numbers.FindEven(n => n % 2 == 0), n => n);

Also note that you created an extension method for IEnumerable<int>, not for Enumerable class

Upvotes: 1

Related Questions