【问题标题】:How to strongly type "Current" when implementing IEnumerator实现 IEnumerator 时如何强输入“Current”
【发布时间】:2021-09-21 17:40:52
【问题描述】:

我们正在类中实现 IEnumerator 和 IEnumerable

    static void Main(string[] args)
    {
       

        ParsingFile data = new ParsingFile();

        foreach (var line in data) // Calls the current, the implicit type of line is object but we want is as a DataRow
        {
            //call MoveNext
        }

        
    }

public class ParsingFile : IEnumerator , IEnumerable 
{

    object IEnumerator.Current //need the object to be of type DataRow to avoid casting in foreach
    {
       //return a DataRow
    }


    public IEnumerator GetEnumerator()
    {
        return this;
    }


    public bool MoveNext()
    {
    //Do something
    }

}

current 的返回类型是 object 但要显式返回 DataRow。请让我们知道实现这一目标的方法是什么?

【问题讨论】:

  • 您需要实现IEnumerable<T> 而不仅仅是IEnumerable。你自己实施它有什么原因吗?这很少需要(或一个好主意)。
  • 另外,不要从GetEnumerator() 盲目地return this:每次消费者调用它时,您都需要返回一个新的枚举器,该枚举器将从序列的开头开始枚举。可以在此处优化并仅在 first 调用GetEnumerator() 时返回this,并在后续调用中返回一个新实例(Linq 会这样做),但首先要有单独的 EnumeratorEnumerable

标签: c# .net ienumerable datarow ienumerator


【解决方案1】:

您必须实现IEnumerator<T>,而不是实现IEnumerator,它的接口指定current 是一个对象。

public class ParsingFile : IEnumerator<DataRow>
{
    public DataRow Current { get; }

    // rest of code ommited for brevity
}

【讨论】:

    【解决方案2】:

    如 jon skeet 所述,请改用 IEnumerable&lt;DataRow&gt;IEnumerator&lt;DataRow&gt;

    我建议永远不要在同一个类中同时实现IEnumeratorIEnumerable。考虑以下几点:

      var myParsingFile = ...
      var dr1 = myParsingFile.First();
      var dr2 = myParsingFile.First();
    

    在您的情况下, dr1 和 dr2 将是不同的对象,这非常令人困惑。

    您也可以查看iterator blocks 以获得更简单的方法来制作枚举器。

    【讨论】:

      【解决方案3】:

      老实说,除非您有 非常 特殊要求,否则最好在此处使用迭代器块,即您只需编写:

      public class ParsingFile : IEnumerable<DataRow>
      {
          // use an iterator block for the typed API
          public IEnumerator<DataRow> GetEnumerator()
          {
              //Do something that involves, perhaps in a loop 
              // yield return someValue;
              // and/or
              // yield break;
          }
      
          // use explicit implementation for the untyped API
          IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
      }
      

      你绝对可以实现你自己的强类型枚举器,这可能(虽然不是严格需要)意味着实现IEnumerator&lt;T&gt;,但是有很多陷阱(例如允许独立并发枚举),这使得编译器能够更安全完成繁重的工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-15
        • 1970-01-01
        • 2022-01-12
        • 1970-01-01
        • 2014-02-22
        • 2011-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多