我正在尝试为 Dictionary
创建一个包装器。
Dictionary
实现 IEnumerable>
,但我希望我的包装类实现 IEnumerable
>。所以我尝试了这个:
public class FooCollection : IEnumerable<Foo>
{
private Dictionary<string, Foo> fooDictionary = new Dictionary<string, Foo>();
public IEnumerator<Foo> GetEnumerator()
{
return fooDictionary.Values.GetEnumerator();
}
// Other wrapper methods omitted
}
但是我收到此错误:
“FooCollection”未实现接口成员“System.Collections.IEnumerable.GetEnumerator()”。 “FooCollection.GetEnumerator()”无法实现“System.Collections.IEnumerable.GetEnumerator()”,因为它没有“System.Collections.IEnumerator”的匹配返回类型。
但是我不明白这个错误,因为 FooCollection.GetEnumerator()
返回一个 IEnumerator
,而 IEnumerator
是一个IEnumerator
。
编辑:
显式实现 IEnumerator.GetEnumerator() 的解决方案有效。然而,我现在想知道为什么当我在 List
上“转到定义”时,我只看到 GetEnumerator 的一个定义:
public List.Enumerator GetEnumerator();
显然,List
可以有一个 GetEnumerator
方法,该方法返回同时实现 < code>IEnumerator 和 IEnumerator
,但我必须为每个都有一个方法?
编辑:
正如下面 LukeH 的回答,List
确实包含显式接口实现。显然,当从元数据生成方法存根时,Visual Studio 不会列出这些内容。 (请参阅上一个问题:为什么 VS 元数据视图不显示显式接口实现的成员 )
在发布此问题之前,我尝试检查 List
(通过“转到定义”在 Visual Studio 中),看看我是否需要实现多个版本的 GetEnumerator。我想这不是最可靠的检查方法。
无论如何,我将其标记为已回答。感谢您的帮助。
I'm trying to create a wrapper for a Dictionary<String,Foo>
.
Dictionary<String,Foo>
implements IEnumerable<KeyValuePair<String,Foo>>
, but I want my wrapper class to implement IEnumerable<Foo>
. So I tried this:
public class FooCollection : IEnumerable<Foo>
{
private Dictionary<string, Foo> fooDictionary = new Dictionary<string, Foo>();
public IEnumerator<Foo> GetEnumerator()
{
return fooDictionary.Values.GetEnumerator();
}
// Other wrapper methods omitted
}
However I get this error:
'FooCollection' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'. 'FooCollection.GetEnumerator()' cannot implement 'System.Collections.IEnumerable.GetEnumerator()' because it does not have the matching return type of 'System.Collections.IEnumerator'.
However I don't understand this error, because FooCollection.GetEnumerator()
returns an IEnumerator<Foo>
, and IEnumerator<Foo>
is an IEnumerator
.
EDIT:
The solution of explicitly implementing IEnumerator.GetEnumerator()
works. However I'm now wondering why when I "Go to definition" on a List<T>
I see only one definition of GetEnumerator:
public List<T>.Enumerator GetEnumerator();
Apparently List<T>
can have a single GetEnumerator
method that returns something that implements both IEnumerator<T>
and IEnumerator
, but I have to have one method for each?
EDIT:
As answered by LukeH below, List<T>
does include the explicit interface implementations. Apparently Visual Studio just doesn't list those when generating method stubs from the metadata. (See this previous question: Why does the VS Metadata view does not display explicit interface implemented members )
Before posting this question I had tried checking List<T>
(via "Go to Definition" in Visual Studio) to see if I needed to implement multiple versions of GetEnumerator. I guess this wasn't the most reliable way to check.
Anyway, I'm marking this as answered. Thanks for your help.
发布评论
评论(7)
添加以下显式接口实现:
虽然
IEnumerator
是一个IEnumerator
,但IEnumerable
的协定返回一个IEnumerator
> 具体来说,不是IEnumerator
Add the following explicit interface implementation:
Although
IEnumerator<T>
is anIEnumerator
, the contract forIEnumerable
returns anIEnumerator
specifically, not anIEnumerator<T>
实现
IEnumerable
时,您还必须显式实现IEnumerable.GetEnumerator()
。通用接口的方法本身作为非通用方法契约的实现是无效的。您可以让一个对象调用另一个对象,或者由于您有一个正在使用其枚举器的子对象,因此只需复制/粘贴即可;When implementing
IEnumerable<T>
, you must also explicitly implementIEnumerable.GetEnumerator()
. The method for the generic interface is not valid in and of itself as an implementation for the non-generic method contract. You can have one call the other, or since you have a child object whose enumerator you are using, just copy/paste;问题是 .NET 中不存在返回类型协方差这样的东西 -
IEnumerator M()
和IEnumerator 。 M()
是完全不同的方法。解决方法是您必须显式实现非通用版本:
The problem is that there is no such thing as return type covariance in .NET -
IEnumerator M()
andIEnumerator<Foo> M()
are completely different methods.The workaround is that you have to implement the non-generic version explicitly:
只要通用 IEnumerable{T} 继承 IEnumerable 您必须实施
IEnumerable.GetEnumerator()
也是如此。您可以像这样明确地执行此操作:As long as generic IEnumerable{T} inherit IEnumerable You have to implement
IEnumerable.GetEnumerator()
as well. You can do it explicitly like:对于您的主要问题,您已经有了几个答案。我将回答您在编辑中提出的问题...
List
类实际上具有三个 不同的GetEnumerator
方法: public 方法当编译时实例本身被键入为List
时调用,并且有两个显式接口实现来满足IEnumerable
/IEnumerable
合约。所有三个方法返回的枚举器对象在幕后都是相同的List.Enumerator
类型。You've already had several answers to your main question. I'll answer the question raised in your edit...
The
List<T>
class actually has three differentGetEnumerator
methods: The public method that's called when the compile-time instance is typed asList<T>
itself, and two explicit interface implementations to meet theIEnumerable
/IEnumerable<T>
contracts. The enumerator objects returned by all three methods are all the sameList<T>.Enumerator
type behind-the-scenes.当您实现通用 IEnumerable 接口时,您还必须实现非通用 IEnumerable 接口。该错误与缺少非泛型方法有关。
When you implement the generic IEnumerable interface, you also have to implement the non generic IEnumerable interface. The error is about the missing non generic method.
这是 IEnumerable 的声明:
注意 new 关键字。
下面是 IEnumerable 的声明:
现在您有了一个 GetEnumerator 方法,但是您要实现这两个方法中的哪一个呢?因此,您需要添加非泛型版本的显式实现:
Here's the declaration of IEnumerable:
notice the new keyword.
Here's the declaration of IEnumerable:
So now you have a GetEnumerator method, but which one of those two are you implementing? Therefore, you need to add an explicit implementation of the non-generic version: