实现C#Dictionary导致错误:没有匹配的返回类型

时间:2013-05-17 03:37:45

标签: c# inheritance dictionary struct

我想了解C#如何实现Dictionary。在我看来,Dictionary应该从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#Dictionary类似地编译?

2 个答案:

答案 0 :(得分:3)

您缺少明确的接口实现:

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;
        }
    }
}

答案 1 :(得分:1)

您混淆了两个不同的界面,即 IEnumerableIEnumerator

外部类(字典类)实现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(非通用)。