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
When should I return an interface, and when should I return a concrete class?
Is it a part of program to an interface, not an implementation for returning an interface?
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:
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).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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With