接口实现和返回类型
List
类实现 IEnumerable
接口。它有一个返回 List
的方法 GetEnumerator
。
我有一个如下的类,它给出一个编译错误,指出 GetEnumerator
的返回类型与接口不匹配。
public class InsertionSortedSet<T> : IEnumerable<T>
{
public struct Enumerator : IEnumerator<T>
{
// Required interface implemented
}
// Other interface methods implemented
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
}
“Entities.Helpers.InsertionSortedSet”未实现接口成员“System.Collections.Generic.IEnumerable.GetEnumerator()”。 “Entities.Helpers.InsertionSortedSet.GetEnumerator()”无法实现“System.Collections.Generic.IEnumerable.GetEnumerator()”,因为它没有“System.Collections.Generic.IEnumerator”的匹配返回类型。
鉴于 List
似乎返回它自己的 Enumerator
类(而不是接口),但它确实实现了 Enumeration
接口我很困惑,因为我看不出我与那堂课有什么不同。
我的设置有什么问题导致它失败,而 List
可以正常工作?
我想返回一个 InsertionSortedSet
而不是接口,因为它可以避免装箱,而我需要将其删除。
The List<T>
class implements the IEnumerable<T>
interface. It has a method GetEnumerator
that returns a List<T>.Enumerator
.
I have a class as below, which gives a compile error saying the return type of GetEnumerator
doesn't match the interface.
public class InsertionSortedSet<T> : IEnumerable<T>
{
public struct Enumerator : IEnumerator<T>
{
// Required interface implemented
}
// Other interface methods implemented
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
}
'Entities.Helpers.InsertionSortedSet' does not implement interface member 'System.Collections.Generic.IEnumerable.GetEnumerator()'. 'Entities.Helpers.InsertionSortedSet.GetEnumerator()' cannot implement 'System.Collections.Generic.IEnumerable.GetEnumerator()' because it does not have the matching return type of 'System.Collections.Generic.IEnumerator'.
Given that List<T>
seems to return it's own Enumerator
class (not the interface) and yet it does implement the Enumeration<T>
interface I'm confused, as I can't see what i've got different to that class.
What's wrong with my setup that makes it fail, where List<T>
works?
I want to return a InsertionSortedSet<T>.Enumerator
rather than the interface as it avoids boxing, which I need to cut out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它会抱怨,因为 GetEnumerator() 返回
IEnumerable
接口的IEnumerator
。为了满足这一要求,您的类型必须返回IEnumerator
(对于IEnumerator
也必须返回一个显式返回值)。但是,很多时候,类希望返回比接口指定的更具体的类型,但接口不允许这样的协变返回类型。因此,要执行此操作,您可以执行
List
的操作并让GetEnumerator()
返回您的特定枚举器,但您还必须显式实现 返回IEnumerator
的IEnumerable.GetEnumerator()
和IEnumerable.GetEnumerator()
的实现返回一个IEnumerator
:如果您查看
List
,您会发现它实现了GetEnumerator()
三次:IEnumerable
Enumerable
如果您愿意,您可以在您的类中执行相同的操作(它应该这样做)就像您开始的方式一样),但如果您这样做,则必须显式实现
IEnumerable.GetEnumerator()
和IEnumerable.GetEnumerator()
如果您导航到定义,您可以通过选择它满足的不同接口(或者通过将
List
实例分配给IEnumerable
来查看对象浏览器中的其他定义或IEnumerable
参考并转到定义):It's complaining because GetEnumerator() returns
IEnumerator<T>
for theIEnumerable<T>
interface. To satisfy, your type must returnIEnumerator<T>
(and an explicit one forIEnumerator
as well).But, many times it's desirable for a class to return a more specific type than the interface specifies, but interfaces don't allow for covariant return types like that. So to do this, you can do what
List<T>
does and haveGetEnumerator()
return your specific enumerator, but you must also implement explicit implementations forIEnumerable.GetEnumerator()
that returns anIEnumerator
and forIEnumerable<T>.GetEnumerator()
that returns anIEnumerator<T>
:If you look at
List<T>
you'll see that it implementsGetEnumerator()
three times:IEnumerable<T>
Enumerable
You could do the same in your class if you wish (which it sould like is the way you began) but if you do that you must explicitly implement
IEnumerable<T>.GetEnumerator()
andIEnumerable.GetEnumerator()
If you navigate to the definition, you can see the other definitions in the object browser by selecting the different interfaces it satisfies (or by assigning a
List<T>
instance to anIEnumerable
orIEnumerable<T>
reference and going to definition):要允许使用
foreach
迭代类,无需实现任何接口。您所需要的只是实现返回您的Enumerator
的 GetEnumerator 方法。但是,如果您希望您的类支持标准迭代接口
IEnumerable
,您可以显式实现它:IEnumerable.GetEnumerator() { return GetEnumerator(); } }
To allow a class to be iterated using
foreach
no need to implement any interface. All what you need is implementing GetEnumerator method that returns yourEnumerator<T>
.But if you want your class to support standard iteration interface
IEnumerable<T>
you may implement it explicity:IEnumerable<T>.GetEnumerator() { return GetEnumerator(); }
您正在寻找的称为返回类型协方差,更多信息请参见C# 支持返回类型吗协方差?
这可以通过使用接口的显式实现来返回
IEnumerator
并实现同名的公共方法来返回 Enumerator 来实现。What you are looking for is called return type covariance, more here Does C# support return type covariance?
This can be achieved by using explicit implementation of interface to return
IEnumerator<T>
and implement public method of same name to return Enumerator.