Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why to Apply AsEnumerable() Method to an Array?

I am reading C# AsEnumerable:

"The IEnumerable interface is a generic interface. This means it defines a template that types can implement for looping. The AsEnumerable method, a generic method, allows you to cast a specific type to its IEnumerable equivalent"

Further on, a code example:

using System;
using System.Linq;

class Program
{
   static void Main()
   {
       // Create an array type.
        int[] array = new int[2];
        array[0] = 5;
        array[1] = 6;
        // Call AsEnumerable method.
        var query = array.AsEnumerable();
        foreach (var element in query)
        {
            Console.WriteLine(element);
        }
    }
}

Sounds like I need to convert an array to an IEnumerable type object to use looping (foreach?).

But applying foreach directly to an array yields exactly the same results:

using System;
//using System.Linq;

class Program
{
    static void Main()
    {
        // Create an array type.
        int[] array = new int[2];
        array[0] = 5;
        array[1] = 6;
        // Call AsEnumerable method.
        //var query = array.AsEnumerable();
        foreach (var element in array)
        {
            Console.WriteLine(element);
        }
    }
}

So, the entire webpage with an explanation of AsEnumerable() method is void for me.
What did I miss?

like image 354

1 Answers

The example is bad and it should feel bad. Here is a better, if somewhat contrived example:

If I have an extension method defined on the, let's say, the array type, like this:

public static class ArrayExtension {

    public static bool Any<T>(this T[] source, Func<T,bool> predicate)
    {
       Console.WriteLine("Undesirable side behaviour");
       SomeResourceIntensiveOperation();

       Console.WriteLine("Inefficient implementation");
       return source.Where(predicate).Count() != 0;
    }

}

and I do

int[] nums = new []{1,2,3,4,5};
nums.Any(n=> n % 2 == 0);

If will execute and run my implementation, even if i do not need that. By doing

nums.AsEnumerable().Any(n => n % 2 == 0);

it will call the default implementation.

The real benefit is when you are using IQueryable implementations (e.g. LINQ-to-SQL), because, for example, the Where for IEnumerable is defined as

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate) 

but the IQueryable.Where is defined with

public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate)

When the IQueryable behaviour is undesireable one can call the AsEnumerable() to force the IEnumerable behaviour.

like image 182
SWeko Avatar answered Sep 18 '22 01:09

SWeko