I have a concrete class implementing an interface with method signature
IEnumerable<T> Foo()
with
List<T> Foo()
The compiler says List<T> Foo
cannot implement IEnumerable<T> Foo
. Why?
I have a concrete class implementing an interface with method signature
IEnumerable<T> Foo()
with
List<T> Foo()
The compiler says List<T> Foo
cannot implement IEnumerable<T> Foo
. Why?
Because the specification does not allow this:
For purposes of interface mapping, a class member A matches an interface member B when:
A and B are methods, and the name, type, and formal parameter lists of A and B are identical.
[...]
(Quoted from the C# 5.0 specification - 13.4.4 Interface mapping)
Not that I know of:
List<T>
returns the IEnumerable<T>
expected by callers of the interfaceYes. .NET 4 supports:
Func<List<T>>
is a Func<IEnumerable<T>>
IEnumerable<List<T>>
is an IEnumerable<IEnumerable<T>
This provides further evidence for the feasiblity of the feature.
Only a member of the C# team can answer that definitely.
But in the absence of further evidence we can assume:
Every feature has a cost to specify, implement test and maintain. So the developers can only implement some features. They'll choose feature which offer a big gain for little work. So there were probably higher priority features and it wasn't considered to be worth their time.
Just use explicit interface implementation:
class FooClass<T> : IFoo
{
public List<T> Foo()
{
//do something
}
IEnumerable<T> IFoo.Foo()
{
return Foo();
}
}
Because you cannot change the return type or any other type in the signature of the method you are implementing in C#.
The language specification for C# says so. Why they made this decision is unknown, but as a wild guess, they probably thought that the potential gain is not worth the cost.
What you can do however is keep the signature as IEnumerable<T>
and simply return a List<T>
.
I can't answer the question of why, but it may be worth noting that this limitation has very little practical impact, since explicit interface implementation allows you to get the desired effect with a small amount of glue code:
public interface IFooable<T>
{
IEnumerable<T> Foo();
}
public sealed class Fooable<T> : IFooable<T>
{
public List<T> Foo()
{
//...
}
IEnumerable<T> IFooable<T>.Foo()
{
return Foo();
}
}