How IEnumeberable might get you in trouble

Quite often I see a bug where a certain Factory method creates an IEnumeberable of objects.

While initially looking at the code you might not notice it, but that sort of code might lead to excessive creation of instances because of multiple enumeration of objects causing the factory method to create more objects that you expect.

For example let examine this bit of innocent looking code:

    public class Employee
    {
        public static int InstanceCount { get; private set; }
        public string Name { get; private set; }
        public string Surname { get; private set; }

        public Employee(string name, string surname)
        {
            this.Name = name;
            this.Surname = surname;
            InstanceCount++;
        }
    }

    public class EmployeeFactory
    {
        public readonly string[] _names = {"John", "Paul", "Peter", "Iain", "Adrian", "Dan" };
        public readonly string[] _surnames = {"Smith", "Hope", "Dill", "Howard", "Gates" };

        public IEnumerable<Employee> GetEmployees()
        {
            return from name in _names from surname in _surnames select new Employee(name, surname);
        }
    }

    [TestFixture]
    public class EnumerableTests
    {
        [Test]
        public void NumberOfObjectsCreatedTest()
        {
            var factory = new EmployeeFactory();
            var employees = factory.GetEmployees();
            if (employees.Count() > 0)
            {
                var employeeNamesStartingWithP = employees.Where(e => e.Name.StartsWith("P"));
                var selectedEmployeeCount = employeeNamesStartingWithP.Count();
                Console.WriteLine(Employee.InstanceCount);
            }
        }
    }

Then number of Employees starting with name ‘P’ would be equal 10, and that thats what the selectedEmployeeCount would contain. The actual number of employees objects created would surprisingly be 60 if you look at Employee.InstanceCount.

Once again the developers forget that each time the IEnumerable is enumerated, in this case, a new instance of Employee is created. The solution is easy:

1) Change the factory to return an array of employees
2) Add to Array() to var employees = factory.GetEmployees().ToArray() to avoid multiple enumeration and thus excessive number of objects being created.

You would still end up with number of instances of 30, the only other way is to inject the filter function (a lambda expression) into the factory method to make sure only the employees matching the filter gets created.

One thought on “How IEnumeberable might get you in trouble

Add yours

  1. You could use IQueryable too?
    IEnumerable executes the select query and loads the data in-memory on client-side and then the filter data, while IQueryable executes the query on server side with all the filters. So IQueryable will be faster.

    Like

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: