使用IDispose错误实现IEnumerator / IEnumerable

时间:2014-03-24 12:07:49

标签: c# .net generics

我一直在尝试构建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] ; }
    }

}

2 个答案:

答案 0 :(得分:2)

IEnumerator<T> inherits from IDisposable,您必须实施它并提供Dispose方法。

IEnumerator<T>继承自IEnumerator,因此您必须实施它并提供GetEnumerator()函数,返回IEnumerator

IEnumerator<T> defines a property Current which returns a T,所以你必须实现一个。


我想混淆是由于通用IEnumerable<T>IEnumerator<T>继承自非通用版本(IEnumerableIEnumerator),要求实现方法具有相同名称但返回值类型不同;并且IEnumerator<T>继承自IDisposable,而IEnumerator则不会。


所以,最后,你的课应该看起来像

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

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

答案 1 :(得分:0)

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

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