Home > .NET Framework > Delegates

Delegates

Imagine we are writing an Employees Collection class which has methods to filter by first name and department. The code looks so similar, can we somehow parameterize it to remove the duplication?

 

using System;
using System.Collections.Generic;

namespace CodingArchitect.Demos.Delegates
{
    public class EmployeesCollection
    {
        private readonly List<Employee> employees =
            new List<Employee>();

        public EmployeesCollection FilterByFirstName(string firstName)
        {
            var matches = new EmployeesCollection();
            foreach (var employee in employees)
            {
                if(string.Equals(employee.FirstName, firstName,
                    StringComparison.InvariantCulture))
                {
                    matches.Add(employee);
                }
            }
            return matches;
        }

        public EmployeesCollection FilterByDepartment(string department)
        {
            var matches = new EmployeesCollection();
            foreach (var employee in employees)
            {
                if (string.Equals(employee.Department, department,
                    StringComparison.InvariantCulture))
                {
                    matches.Add(employee);
                }
            }
            return matches;
        }

        private void Add(Employee employee)
        {
            employees.Add(employee);
        }
    }
    public class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Department { get; set; }
    }
}

Parameterize Method refactoring immediately comes to mind, only in this case the parameter should be a function which does the actual filtering. Passing functions as parameters is perfectly valid in C#. Now the condition alone can be passed as a delegate to the filter method. I am reusing the Predicate<T> delegate defined in the BCL. This is exactly what the FindAll method on the List<T> type in BCL does.

 

using System;
using System.Collections.Generic;

namespace CodingArchitect.Demos.Delegates
{
    public class EmployeesCollection
    {
        private readonly List<Employee> employees =
            new List<Employee>();

        public EmployeesCollection Filter(Predicate<Employee> condition)
        {
            var matches = new EmployeesCollection();
            foreach (var employee in employees)
            {
                if (condition(employee))
                {
                    matches.Add(employee);
                }
            }
            return matches;
        }

        private void Add(Employee employee)
        {
            employees.Add(employee);
        }
    }
    public class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Department { get; set; }
    }
}

The condition predicate can now be passed from the call site using a delegate (syntactic sugar like anonymous delegates, lambda expressions make it easier further).

Advertisements
  1. No comments yet.
  1. May 9, 2011 at 3:01 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: