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