【问题标题】:Implementing IEnumerator/ IEnumerable with IDispose error使用 IDispose 错误实现 IEnumerator/IEnumerable
【发布时间】:2014-03-24 20:32:30
【问题描述】:

我一直在尝试构建 IEnumorator 以允许我使用 foreach 语句快速将从 JSON 格式的字符串中提取的大量行插入到这些嵌套对象中。 Applines 类完全由 String Get/Set 语句组成。

由于某种原因,我收到三个指向类头的错误。我无法理解 a) 为什么以及如何我需要实施 IDisposable b) 为什么编译器不同意我的返回类型。

“AppAnnieImport”未实现接口成员“System.Collections.IEnumerable.GetEnumerator()”。 “AppAnnieImport.GetEnumerator()”无法实现“System.Collections.IEnumerable.GetEnumerator()”,因为它没有匹配的返回类型“System.Collections.IEnumerator”。

“AppAnnieImport”没有实现接口成员“System.IDisposable.Dispose()”

“AppAnnieImport”未实现接口成员“System.Collections.Generic.IEnumerator.Current”。 “AppAnnieImport.Current”无法实现“System.Collections.Generic.IEnumerator.Current”,因为它没有匹配的返回类型“AppLines”。

public class AppAnnieImport : IEnumerator<AppLines>, IEnumerable<AppLines>
{
    public int code { get; set; }
    public DateTime end_date { get; set; }
    public string vertical { get; set; }
    public string granularity { get; set; }
    public string device { get; set; }
    public List<AppLines> AppLine { get; set; }
    private int position;

    //IEnumerator and IEnumerable require these methods.
    public IEnumerator<AppLines> GetEnumerator()
    {
        return (IEnumerator<AppLines>)this;
    }

    //IEnumerator
    public bool MoveNext()
    {
        position++;
        return (position < AppLine.Count);
    }

    //IEnumerable
    public void Reset()
    { position = 0; }

    //IEnumerable
    public object Current
    {
        get { return (AppLine.ToArray())[position] ; }
    }

}

【问题讨论】:

  • 将光标放在IEnumerator&lt;AppLines&gt; 上并按Ctrl+。并选择实现接口。基本上你需要实现GetEnumerator的通用和非通用版本。
  • 没有什么可以添加到问题的编译器解释中。
  • 我不会同时创建 IEnumerable 和 IEnumerator 类,实现 IEnumerable,如果您需要自定义 IEnumerator,请将其作为单独的类。
  • 我同意@LasseV.Karlsen 的观点,至少在公共类中(有时在私有类或内部类中都可以很方便地实现,其中混淆的可能性要小得多)。

标签: c# .net generics


【解决方案1】:

IEnumerator&lt;T&gt; inherits from IDisposable,所以你也必须实现它并提供一个Dispose 方法。

IEnumerator&lt;T&gt; 继承自 IEnumerator,因此您也必须实现它并提供一个返回 IEnumeratorGetEnumerator() 函数。

IEnumerator&lt;T&gt; defines a property Current which returns a T,所以你必须实现一个。


我猜这个混淆是因为泛型IEnumerable&lt;T&gt;IEnumerator&lt;T&gt;继承自非泛型版本(IEnumerableIEnumerator),要求实现具有相同名称但返回值不同的方法类型; IEnumerator&lt;T&gt; 继承自 IDisposableIEnumerator 没有。


所以,最后,你的类应该是这样的

public class AppAnnieImport : IEnumerator<AppLines>, IEnumerable<AppLines>
{
    public int code { get; set; }
    public DateTime end_date { get; set; }
    public string vertical { get; set; }
    public string granularity { get; set; }
    public string device { get; set; }
    public List<AppLines> AppLine { get; set; }
    private int position;

    //IEnumerator and IEnumerable require these methods.
    public IEnumerator<AppLines> GetEnumerator()
    {
        return (IEnumerator<AppLines>)this;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return (IEnumerator<AppLines>)this;
    }

    //IEnumerator
    public bool MoveNext()
    {
        position++;
        return (position < AppLine.Count);
    }

    //IEnumerable
    public void Reset()
    { position = 0; }

    //IEnumerable
    object IEnumerator.Current
    {
        get { return (AppLine.ToArray())[position] ; }
    }

    public AppLines Current
    {
        get { return (AppLine.ToArray())[position] ; }
    }

    public void Dispose()
    {
        // do something or not
    }
}

使用显式接口实现(您可能还想摆脱代码重复)。

【讨论】:

  • 谢谢,这太完美了
【解决方案2】:

首先在您的自定义逻辑中重用内部列表的方法和层:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    public class AppLines { }
    public class AppAnnieImport : IEnumerator<AppLines>, IEnumerable<AppLines>
    {
        public int code { get; set; }
        public DateTime end_date { get; set; }
        public string vertical { get; set; }
        public string granularity { get; set; }
        public string device { get; set; }
        public List<AppLines> appLines { get; set; }
        private int position;

        AppLines IEnumerator<AppLines>.Current
        {
            get { return ((IEnumerator<AppLines>)this.appLines).Current; }
        }

        public void Dispose()
        {
            ((IEnumerator<AppLines>)this.appLines).Dispose();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.appLines.GetEnumerator();
        }

        object System.Collections.IEnumerator.Current
        {
            get { return ((System.Collections.IEnumerator)this.appLines).Current; }
        }

        public bool MoveNext()
        {
            return ((System.Collections.IEnumerator)this.appLines).MoveNext();
        }

        public void Reset()
        {
            ((System.Collections.IEnumerator)this.appLines).Reset();
        }

        IEnumerator<AppLines> IEnumerable<AppLines>.GetEnumerator()
        {
            return ((IEnumerable<AppLines>)this.appLines).GetEnumerator();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    相关资源
    最近更新 更多