Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should we avoid IEnumerable as an input when designing public API?

Consider following example.

Assume I developed a library that will be used by a third party. The library has a method that accepts IEnumerable, which is nice because it abstracts from the implementation of the collection passed. However, lazy evaluation occurs when I retrieve the input parameter.

public interface IStorage<in T>
{
  void Store(IEnumerable<T> values);
}

public class FileStorage<T> : IStorage<T>
{
  public void Store(IEnumerable<T> values)
  {
    foreach (var value in values) { /*Evaluation of IEnumerable*/}
  }
}

Some client uses my library in the following way:

  IEnumerable<int> values;
  try
  {
    values = new[] { "1", "2", "three" }.Select(int.Parse);
  }
  catch (Exception)
  {
    values = Enumerable.Empty<int>();
  }

  var storage = new FileStorage<int>();
  storage.Store(values);

That will cause an exception inside the Store method where evaluation happens. If I designed the Store method to take List<T> I'd be sure that it is safely enumerable collection of Ts. The question is should we avoid IEnumerable when designing API or whether should we allow and enumerate it in safe context when needed as it might raise exceptions.

like image 815
nan Avatar asked Oct 20 '25 12:10

nan


1 Answers

According to the Framework Design Guidelines book by Krzysztoc Cwalina and Brad Adams.

http://blogs.msdn.com/b/kcwalina/archive/2008/01/03/frameworkdesignguidelines2ndedition.aspx

Its is recommended that you do...

an extraction from page 252 (8.3.1)

Collection Parameters

DO use the least-specialized type possible as a parameter type. Most members taking collections as parameters use the IEnumerable interface

 public void PrintNames(IEnumerable<string> names) {
      foreach(string name in names) {
          Console.WriteLine(name);
      } }

AVOID using ICollection or ICollection as a parameter just to access the Count property.

Instead consider IEnumerable or IEnumerable and dynamically checking whether the object implements ICollection or ICollection

By the way its a great book and a worthwhile read, currently really enjoying it. P.S. the guys who wrote this, helped write the .NET framework

like image 187
Mike Avatar answered Oct 23 '25 01:10

Mike