接口实现和返回类型

发布于 2024-12-25 05:57:51 字数 1166 浏览 0 评论 0原文

List 类实现 IEnumerable 接口。它有一个返回 List.Enumerator 的方法 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.Enumerator 而不是接口,因为它可以避免装箱,而我需要将其删除。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

別甾虛僞 2025-01-01 05:57:51

它会抱怨,因为 GetEnumerator() 返回 IEnumerable 接口的 IEnumerator 。为了满足这一要求,您的类型必须返回 IEnumerator(对于 IEnumerator 也必须返回一个显式返回值)。

但是,很多时候,类希望返回比接口指定的更具体的类型,但接口不允许这样的协变返回类型。因此,要执行此操作,您可以执行 List 的操作并让 GetEnumerator() 返回您的特定枚举器,但您还必须显式实现 返回 IEnumeratorIEnumerable.GetEnumerator()IEnumerable.GetEnumerator() 的实现返回一个 IEnumerator

    // This is your specific version, like List<T> does
    public Enumerator GetEnumerator()
    {
        return new Enumerator(this);
    }

    // This is the one with the return value IEnumerator<T> expects
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator(this);
    }

    // Plus, it also expects this as well to satisfy IEnumerable
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

如果您查看 List,您会发现它实现了 GetEnumerator() 三次:

  • 一次显式地用于 IEnumerable
  • 一次显式地用于 Enumerable
  • 一次具有非常特定于列表的返回

如果您愿意,您可以在您的类中执行相同的操作(它应该这样做)就像您开始的方式一样),但如果您这样做,则必须显式实现 IEnumerable.GetEnumerator()IEnumerable.GetEnumerator()

如果您导航到定义,您可以通过选择它满足的不同接口(或者通过将 List 实例分配给 IEnumerable 来查看对象浏览器中的其他定义或 IEnumerable 参考并转到定义):

对象资源管理器的屏幕截图

It's complaining because GetEnumerator() returns IEnumerator<T> for the IEnumerable<T> interface. To satisfy, your type must return IEnumerator<T> (and an explicit one for IEnumerator 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 have GetEnumerator() return your specific enumerator, but you must also implement explicit implementations for IEnumerable.GetEnumerator() that returns an IEnumerator and for IEnumerable<T>.GetEnumerator() that returns an IEnumerator<T>:

    // This is your specific version, like List<T> does
    public Enumerator GetEnumerator()
    {
        return new Enumerator(this);
    }

    // This is the one with the return value IEnumerator<T> expects
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator(this);
    }

    // Plus, it also expects this as well to satisfy IEnumerable
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

If you look at List<T> you'll see that it implements GetEnumerator() three times:

  • Once explicitly for IEnumerable<T>
  • Once explicitly for Enumerable
  • Once with a very list-specific return

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() and IEnumerable.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 an IEnumerable or IEnumerable<T> reference and going to definition):

Screenshot of Object Explorer

段念尘 2025-01-01 05:57:51

要允许使用 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 your Enumerator<T>.

But if you want your class to support standard iteration interface IEnumerable<T> you may implement it explicity: IEnumerable<T>.GetEnumerator() { return GetEnumerator(); }

沉睡月亮 2025-01-01 05:57:51

您正在寻找的称为返回类型协方差,更多信息请参见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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文