Small in, Big out

Posted by: Eric Gunnersons C# Compendium, on 20 Nov 2012 | View original | Bookmarked: 0 time(s)

Ive come across some code that is using and overusing IEnumerable<T>, and thought it might be of general interest.

Consider the following method signatures:

IEnumerable<string> Process(List<string> input);

IList<string> Process(IEnumerable<string> input);

Of the two, which is the better choice? Write down your answer.

There are really two questions what is the best choice for input parameters, and what is the best choice for return values. Ill cover them separately:

Small In

The input parameter should be the smallest (ie least functional) type that allows the method to efficiently do what it needs to do. Ive seen methods like this:

void Process(List<string> input)
{
    foreach (string in input)
    {
       
    }
}

(or maybe the Linq equivalent).

In this case, you are just making things harder for the caller; all you really need is an IEnumerable<string>, so thats what you should specify. On the other hand, Ive also seen code like this:

void Process(IEnumerable<string> items, IEnumerable<ReferenceItem> referenceItems)
{
    var lookup = referenceItems.ToDictionary(referenceItem => referenceItem.Name, referenceItem => referenceItem.Contents)'
   
}

This code takes a simple enumerable, and constructs a dictionary out of it. This is worse than the first case; if you need a dictionary, ask for a dictionary.

Big Out

Output parameters should be the biggest (ie most functional) type that is acceptable for the scenario. Ive seen methods like this:

IEnumerable<string> Process(List<string> input)
{
    List<string> items = new List<string>();

    // fill list here

    return items;
}

The developer has created a beautiful, functional list object, but theyre only going to let the caller enumerate over it. This often leads to my favorite outcome, where the caller writes something like:

List<string> items = new List<string>(myClass,Process(input));

Dont do that. Just return the List<string> or perhaps the IList<string>.

Return values arent as cut-and-dried as input parameters, however. If we modify the previous example as follows:

IList<string> Process(List<string> input)
{
    m_items = new List<string>();

    // fill list here

    return m_items;

In this example, the class is retaining ownership of the list, and in that case, it probably doesnt want to give it out to somebody who could clear it, or replace all the strings with the string Haddock. If the class is going to retain ownership, it should use a return type that prevents bad things like that from happening.

Category: Events | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 692 | Hits: 15

Similar Posts

  • $.fadeTo/fadeOut() operations on Table Rows in IE fail more
  • Oredev Wrap-Up more
  • MVC or Web Forms? A Dying Question more
  • Telerik OpenAccess WCF Wizard October CTP more
  • Migrating to Postgresql with my friend NHibernate more
  • No JavaScript IntelliSense in VS 2010 Beta 2? Reset your Settings more
  • Formatting Text in RadControls for WinForms Q3 2009 more
  • My History of Visual Studio (Part 2) more
  • Private Extension Methods more
  • Audio junkie – FooBar 2000 more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD