Al.
Al.

Reputation: 875

Issue with extension method

Code:

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

namespace LambdaExtensionEx
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] myStrngs = new string[] { "Super","Simple","Okay"};
            IEnumerable<string> criteraStrngs = myStrngs.WhereSearch<string>(delegate(string s)
            {
                return s.StartsWith("s");
            });

            string s1 = "dotnet";
            int count = s1.GetCount();

            Console.ReadLine();
        }
    }

    public static class MyExtension
    {
        public delegate bool Criteria<T>(T Value);

        public static IEnumerable<T> WhereSearch<T>(this IEnumerable<T> values, Criteria<T> critera)
        {
            foreach (T value in values)
                if (critera(value))
                    yield return value;
        }

        public static int GetCount(this string value)
        {
            return value.Count();
        }
    }
}

I am able to call GetCount extension method and I get result in 'count'. But WhereSearch is not being called in any time and not getting result. What mistake am I doing?

Upvotes: 0

Views: 86

Answers (2)

Jay
Jay

Reputation: 10128

Your extension methods class doesn't make much sense - why don't you just do this?

 class Program
{
    static void Main(string[] args)
    {
        string[] myStrngs = new string[] { "Super", "Simple", "Okay" };
        IEnumerable<string> criteraStrngs = myStrngs.Where(x => x.StartsWith("s"));

        string s1 = "dotnet";
        int count = s1.Count();

        Console.ReadLine();

    }
}

As stated by Darin Dimitrov previously - you will still need to enumerate criteriaStrngs to get a result out of it - which is what was wrong with your original code.

HTH

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039368

You need to start enumerating over the result returned by the WhereSearch function if you want it to get executed. The reason for that is because this function yield returns an IEnumerable<T>. What the C# compiler does is build a state machine and doesn't execute the function immediately until the calling code starts enumerating over the result.

For example:

// The function is not executed at this stage because this function uses 
// yield return to build an IEnumerable<T>
IEnumerable<string> criteraStrngs = myStrngs.WhereSearch<string>(delegate(string s)
{
    return s.StartsWith("s");
});
// Here we start enumerating over the result => the code will start executing
// the function.
foreach (var item in criteraStrngs)
{
    Console.WriteLine(item);
}

Another example is calling some of the LINQ extension methods such as .ToList() on the result which will actually enumerate and call the function:

IEnumerable<string> criteraStrngs = myStrngs.WhereSearch<string>(delegate(string s)
{
    return s.StartsWith("s");
})
.ToList();

For more details on how lazy loading works in this case you may take a look at the following post.

Upvotes: 5

Related Questions