Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should the return type of a method declaration be interface or concrete class?

In general scenario, the interface or abstract class is often the appropriate decision, am I right?

But in some cases, it looks like the concrete class is better. For instance,

public string Replace(string old, string new)

The Replace method of String returns a concrete class. (It's just an example, although String doesn't implement any interfaces.)

My question is

  1. When should I return an interface, and when should I return a concrete class?

  2. Is it a part of program to an interface, not an implementation for returning an interface?

like image 812
Kirin Yao Avatar asked Mar 07 '12 09:03

Kirin Yao


1 Answers

It depends.

I've seen this question asked a couple of times, and here's a nice example to illustrate the "it depends" answer.

Consider the following class:

public class MyClass
{
    public static IEnumerable<int> Test()
    {
        return new List<int> { 2, 3, 4 };
    }

    public static List<int> Test2()
    {
        return new List<int> { 2, 3, 4 };
    }
}

Test returns an IEnumerable and Test2 returns a concrete implementation of the IEnumerable interface (List in that case). What is the best method? Test or Test2?

Actually, both are semantically different:

  • As Test only returns an IEnumerable, it implies that it's a part of the method contract that the developer uses the returned object in an enumeration (foreach).
  • As Test2 returns a List instance, it allows the user to access to the objects of the List by index. It's a totally different utilization of the returned object.

private static void Main(string[] args)
{
    foreach (var z in MyClass.Test())
    {
        Console.WriteLine(z);
    }

    var f = MyClass.Test2()[0];

    Console.ReadKey();
}

If you expect the developer to use the returned object in an enumeration only, then you could use the interface as return type. If you expect the developer to use methods/properties of the concrete implementation of the interface (in the above example, access to object by index), then you could return a concrete type.

Also remember that sometimes you have no choice. For example, if you want to expose a public collection that should be used for a Silverlight binding, then you should return ObservableCollection<T>, not IEnumerable<T>, because the binding system actually needs the method/properties/behavior of the ObservableCollection class (IEnumerable would be not sufficient for the binding to work).

What you should avoid is a method that returns IEnumerable<T> and that is used with ToList() every time.

like image 105
ken2k Avatar answered Oct 30 '22 23:10

ken2k