C# 接口实现 - 为什么这不能构建?
抱歉,如果之前有人问过这个问题,但实际上不可能用谷歌搜索。我认为 int 数组实现了 IEnumerable,因此 Thing 应该能够实现 IThing。怎么没有呢?
public interface IThing
{
IEnumerable<int> Collection { get; }
}
public class Thing : IThing
{
public int[] Collection { get; set; }
}
请注意,这
public class Thing : IThing
{
public int[] Array { get; set; }
public IEnumerable<int> Collection
{
get
{
return this.Array;
}
}
}
很好。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
对于要实现的接口,方法签名和返回类型必须相同,因此 int[] 可转换为 IEnumerable 的事实恐怕没有什么区别。
For an interface to be implemented the method signature and return type must be identical, so the fact that an int[] is convertible to an IEnumerable makes no difference I'm afraid.
接口实现必须准确实现接口。这会阻止您返回实现该接口作为成员的类型。
如果您希望这样做,一种选择是显式实现接口:
这允许类的公共 API 使用具体类型,但可以正确实现接口实现。
例如,通过上面的内容,您可以编写:
The interface implementation must implement the interface exactly. This prevents you from returning a type that implements that interface as the member.
If you wish to do this, one option is to implement the interface explicitly:
This allows your public API for the class to use the concrete type, but the interface implementation to be fulfilled correctly.
For example, with the above, you can write:
不同实现中属性的返回类型不同 - 返回
int[]
与返回IEnumerable
不同。就实现接口而言 - 类型必须完全匹配。
这应该可以正常工作:
The return type of the properties in the different implementations is different - returning a
int[]
is not the same as returning aIEnumerable<int>
.As far as implementing the interface - the types must match exactly.
This should work just fine:
您的实现应该完全按原样实现接口。
Your implementations should implement interface exactly as it is.
因为 的签名
与 的签名不一样
并且当您实现接口时,签名应该完全相同。
Because the signature of
Is not the same than the signature of
And when you implement an interface, the signatures should be exactly the same.
这就是协变/逆变可以派上用场的地方。此功能允许您在泛型上定义输入/输出标记,并允许您执行以下操作:
然后,您可以定义其他实现,然后仍然将它们一起用作
IThing>
s。与显式接口实现相比,这种方法的优点是您保证 IThing.Collection 与 Thing.Collection 完全相同,而使用显式实现时,它们实际上是不同的方法,因此不存在这样的方法保证。当然,缺点是您必须更明确一点,因此它使代码看起来有点“嘈杂”。
不知道为什么 C# 编译器无法隐式地解决这个问题;我的猜测是,使用额外的检查进行编译会花费太长时间。
This is where covariance / contravariance can come in handy. This feature lets you define in/out tags on your generics and lets you do the following:
Then that will allow you to define other implementations, and then still use them together as
IThing<IEnumerable<int>>
s.The advantage of this approach over the explicit interface implementation is that you guarantee that IThing.Collection is the exact same method as Thing.Collection, whereas with explicit implementation, they're actually different methods so there's no such guarantee. The disadvantage of course being that you have to be a little more explicit and so it makes the code a bit "noisier" to look at.
Not sure why the C# compiler couldn't figure this out implicitly; my guess being that it'd just take too long to compile with that extra check.
如果您阅读接口的定义,您会注意到它说“ ...类的相应成员必须是公共的、非静态的,并且与接口成员具有相同的名称和签名。”
虽然数组或列表实现了 IEnumerable,但它不是 IEnumerable 对象。那是你的问题。
您的签名必须匹配才能正常工作。您会注意到
public List;集合{获取;放; }
也不起作用。您需要更改接口的属性定义,或者让您的实现返回IEnumerable
,就像第二个工作示例一样。If you read the definition of Interfaces you'll notice that it says "...the corresponding member of the class must be public, non-static, and have the same name and signature as the interface member."
While an array or a List implements IEnumerable, it is not an IEnumerable object. That's your problem.
Your signature must match for it to work. You'll notice that
public List<int> Collection { get; set; }
will not work, either. You will either need to change your Interface's property definition, or have your implementation return anIEnumerable <int>
as you have with your second working example.