Extension Methods with Lambda Expressions and IEnumerable Interface Implementation

Often we write lot of extension methods which helps us in consolidating logic and performing operations on objects in a easy way. In this tutorial I m going to narrate on how to implement IEnumerable<T> on extension methods which helps us in extending our extension method on every object which implements IEnumerable implementation say Arrays, Lists, Custom object etc. So we get wide coverage of different objects on which we can use our extension method.

Also in this tutorial, I have used Func<T,TResult> Delegate, using which I passed a Lambda function as a parameter to our extension method. With this we get flexibility to use lambda expression so that we can achieve anonymous methods and clean code.

Lets first get started by creating a Domain Model –

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

namespace ExtensionsDemo
{
    class Question
    {
        public int QuestionId { get; set; }
        public string QuestionTitle { get; set; }
        public string QuestionText { get; set; }
        public List<string> QuestionTags { get; set; }
    }
}

Now lets create an implementation(wrapper) for our Question Class – QuestionsBag, which will list out all questions. We are going to use our extension method on top of an instance of this object. This class implements IEnumerable<Question> interface.

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

namespace ExtensionsDemo
{
    class QuestionsBag : IEnumerable<Question>
    {
        public List<Question> Questions { get; set; }

        public IEnumerator<Question> GetEnumerator()
        {
            return Questions.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

 

Create Extensions Class for writing a Search extension for our QuestionsBag.

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

namespace ExtensionsDemo
{
    static class Extensions
    {
        public static IEnumerable<Question> Search(this QuestionsBag bag, Func<Question, bool> searchCriteria)
        {
            foreach (Question _question in bag)
            {
                if (searchCriteria(_question))
                    yield return _question;
            }
        }
    }
}

 

Now the implementation would be as follows –

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

namespace ExtensionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            QuestionsBag bag = new QuestionsBag();
            bag.Questions = new List<Question>();

            bag.Questions.Add(
                new Question 
                { 
                    QuestionId = 1, 
                    QuestionTitle = "What is ASP.Net MVC?", 
                    QuestionText = "ASP.Net MVC", 
                    QuestionTags = new List<string>{ "MVC", "Web" } 
                });

            bag.Questions.Add(
                new Question
                {
                    QuestionId = 2,
                    QuestionTitle = "What is SQL Server?",
                    QuestionText = "SQL Server",
                    QuestionTags = new List<string> { "SQL", "DB" }
                });

            bag.Questions.Add(
                new Question
                {
                    QuestionId = 3,
                    QuestionTitle = "What is WCF?",
                    QuestionText = "WCF",
                    QuestionTags = new List<string> { "WCF", "Services" }
                });

            bag.Questions.Add(
                new Question
                {
                    QuestionId = 4,
                    QuestionTitle = "What is ASP.Net?",
                    QuestionText = "ASP.Net",
                    QuestionTags = new List<string> { "ASP.Net", "Web" }
                });

            IEnumerable<Question> result = bag.Search(p => p.QuestionTags.Contains("Web") && p.QuestionTitle.Contains("What"));

            Console.WriteLine("Total question found - " + result.Count().ToString());
            foreach (Question _question in result)
            {
                Console.WriteLine(_question.QuestionTitle);
            }

            Console.ReadLine();
        }
    }
}

 

When you run the above code, you should be able to search all questions which got “Web” tag associated with it and also which contains “What” keyword in Question’s Title.

Extensions-IEnumerable

When the same program executed to search questions with tag “Web” and which contains “WCF” in question title, it will give you 0 results as no question supports the search criteria.

Extensions-IEnumerable1

You may also like...

  • MANISH

    hello,

    isn’t it like you’ve given the functionality of “Where” extended method in your “search” method? what’s benefit of doing this exercise?

  • RamiVemula

    @Manish – what if you need to have specific business constraints to be met?