8r22dw
Last Updated: February 25, 2016
·
1.211K
· keboo

Re-writing methods using LINQ

Tonight’s problem, how to re-write a method using LINQ. I am a huge fan of LINQ and try to utilize it power and simplicity whenever possible.

Consider the following problem. You have a class that exposes a getTotalItems method and a getItemAtIndex method. Something like this:

public class EmployeeManager
{
    pulic int GetTotalEmployees()
    { ... }

    public Employee GetAtIndex(int index)
    { ... }
}

Now let assume that we want to write a method, that returns an IEnumerable<Employee> to allow us to iterate over all of the employees. Something like this will do the trick:

public IEnumerable<Employee> GetEmployees()
{
    var rv = new List<Employee>();
    for (int i = 0; i < GetTotalEmployees(); i++)
    {
        rv.Add(GetAtIndex(i));
    }
    return rv;
}

Now the question, is it possible to re-write this method using LINQ?
Of course it is:

public IEnumerable<Employee> GetEmployees()
{
    return from i in Enumerable.Range(0, GetTotalEmployees())
           select GetAtIndex(i);
}

The first thing to notice is the call to Enumerable.Range allows you to enumerate over a range of values (start, and count respectively).

It is important to note is that this solution does not behave the same as the initial method. The first method executes immediately, iterating over the employees, builds up a list, and returns it. This solution takes advantage of LINQ’s deferred execution. This is typically a good thing, however, it may yield un-expected results if the caller incorrectly assumes that the method executes immediately.

Source: http://dotnetgeek.tumblr.com/post/31843943258/re-writing-methods-using-linq

Say Thanks
Respond

3 Responses
Add your response

2522
Rick2011 500

Having a collection you can only access by index is not a great abstraction.

The EmployeeManager class should not exist in this form. In this example it is just a list. So use List<Employee> (and it will implement IEnumerable<Employee> as well).

Readers, if you think that you can LINQify your classes like this and you find this example a useful step, your problem is that the class you try to LINQify is probably doing multiple things (needs refactoring) or should be replaced by a List<> or Array<>.

over 1 year ago ·
2574

@rickbeerendonk
Thank you for your comment. You are correct that a class like the EmployeeManager referenced above is a poor design for a class. However, the purpose of the post was to show how to re-write a method that was using a for loop by utilizing the Enumerable.Range method. Creating a complete real-world example requires much too much code and takes away from showing a simple technique; in this case a way to replace a for loop.

over 1 year ago ·
2616
Rick2011 500

@keboo Your example seems to promote a class that should be a list and an abstraction of a collection that is accessed by index and not by IEnumerable.

In a real design, I would say your class violates the Dependency Inversion Principle.

I am sure you can come up with much better for-loop elimination examples.

over 1 year ago ·