实现c#字典会导致错误:没有匹配的返回类型
本文关键字:返回类型 错误 字典 实现 | 更新日期: 2023-09-27 18:14:15
我想了解c#是如何实现字典的。在我看来,字典应该继承IEnumerable,这需要方法实现:
IEnumerable GetEnumerator()
然而,c# Dictionary实现了:
Dictionary<T>.Enumerator GetEnumerator()
其中Enumerator是继承IEnumerator的嵌套结构体。
我已经创建了一个这种关系的例子:
public interface IFoo
{
IFoo GetFoo();
}
public abstract class Foo : IFoo
{
public abstract FooInternal GetFoo();
public struct FooInternal : IFoo
{
public IFoo GetFoo()
{
return null;
}
}
}
但是,这不会编译,导致以下错误:
Error 2 'Foo' does not implement interface member 'IFoo.GetFoo()'. 'Foo.GetFoo()' cannot implement 'IFoo.GetFoo()' because it does not have the matching return type of 'CodeGenerator.UnitTests.IFoo'. Foo.cs 14
有什么想法我可能做错了吗?c#是如何实现字典的?如何使示例代码编译类似于c#字典?
您缺少一个显式接口实现:
public abstract class Foo : IFoo
{
public abstract FooInternal GetFoo();
// start here
IFoo IFoo.GetFoo()
{
return GetFoo();
}
// end here
public struct FooInternal : IFoo
{
public IFoo GetFoo()
{
return null;
}
}
}
你混淆了两个不同的接口,即 IEnumerable
和IEnumerator
。
外部类,字典类,实现IEnumerable
。这涉及到外部类有一个方法GetEnumerator
。这个方法返回一个嵌套(内部)结构体的实例。
内部结构实现IEnumerator
。要实现IEnumerator
,你必须有一个MoveNext
方法和一个Current
属性。
此外,还有显式接口实现的问题,Andrey Shchekin的回答中也提到了这个问题。这段代码是合法的,类似于Dictionary<,>
:
public interface IFoo // corresponds to IEnumerable
{
IBar GetBar();
}
public interface IBar // corresponds to IEnumerator
{
}
public class Foo : IFoo
{
// public method that has BarInternal as return type
public BarInternal GetBar()
{
return new BarInternal();
}
// explicit interface implementation which calls the public method above
IBar IFoo.GetBar()
{
return GetBar();
}
public struct BarInternal : IBar
{
}
}
也可以通过公共方法"直接"(而不是显式)实现IFoo
,但是声明的返回类型必须匹配:
public class Foo : IFoo
{
// public method that directly implements the interface
public IBar GetBar()
{
return new BarInternal();
}
public struct BarInternal : IBar
{
}
}
Dictionary<,>
没有以这种更简单的方式编写的原因,我猜是您对嵌套结构进行了装箱。
请注意,当您使用foreach
通过Dictionary<,>
时,c#编译器首先搜索具有确切名称GetEnumerator
的公共非泛型无参数实例方法。如果找到这样的方法,就使用它,编译器不关心IEnumerable
。因此,对于Dictionary<,>
,在foreach
期间使用稍微更优的公共方法,该方法不实现接口。
在MSDN上记录了显式接口实现。参见Dictionary<TKey, TValue>.IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator
(通用)和Dictionary<TKey, TValue>.IEnumerable.GetEnumerator
(非通用)