为什么在实现接口时不能使用兼容的具体类型 [英] Why can't I use a compatible concrete type when implementing an interface
问题描述
我希望能够做这样的事情:
I would like to be able to do something like this :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
public interface IFoo
{
IEnumerable<int> integers { get; set; }
}
public class Bar : IFoo
{
public List<int> integers { get; set; }
}
}
为什么编译器会抱怨..?
Why does the compiler complains..?
Error 2 'Test.Bar' does not implement interface member 'Test.IFoo.integers'. 'Test.Bar.integers' cannot implement 'Test.IFoo.integers' because it does not have the matching return type of 'System.Collections.Generic.IEnumerable<int>'.
我知道接口说 IEnumerable 并且该类使用列表,但是列表 is 是 IEnumerable.....
I understand that the interface says IEnumerable and the class uses a List, but a List is an IEnumerable.....
我能做什么?我不想在类中指定 IEnumerable,我想使用实现 IEnumerable 的具体类型,比如 List...
what can I do? I do not want to specify IEnumerable in the class, I want to use a concrete type that implements IEnumerable, like List...
推荐答案
这是一个类型协方差/逆变问题(参见 http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#C.23).
This is a Type Covariance/Contravariance issue (see http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#C.23 ).
有一个解决方法:使用显式接口,如下所示:
There's a workaround: use explicit interfaces, like so:
public class Bar : IFoo {
private IList<int> _integers;
IEnumerable<int> IFoo.integers {
get { return _integers };
set { _integers = value as IList<int>; }
}
public IList<int> integers {
get { return _integers; }
set { _integers = vale; }
}
}
请注意,integers
应为 TitleCased 以符合 .NET 的准则.
Note that integers
should be TitleCased to conform to .NET's guidelines.
希望你能在上面的代码中看到问题:IList
与 IEnumerable
兼容,仅适用于访问器,不适用于设置.如果有人调用 IFoo.integers = new Qux
(其中 Qux : IEnumerable
但 not Qux : IList
).
Hopefully you can see the problem in the code above: IList<int>
is compatible with IEnumerable<int>
only for the accessor, but not for setting. What happens if someone calls IFoo.integers = new Qux<int>()
(where Qux : IEnumerable<int>
but not Qux : IList<int>
).
这篇关于为什么在实现接口时不能使用兼容的具体类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!