【问题标题】:Map enumerator (not enumerable) type to an enumerator of another type将枚举器(不可枚举)类型映射到另一种类型的枚举器
【发布时间】:2019-01-04 22:22:37
【问题描述】:

如何将IEnumerator<KeyValuePair<TKey, TValue>> 转换为包含键值对中的键的IEnumerator<TKey>

更一般地说,如果有从TSourceTTarget 的转换,我如何将IEnumerator<TSource> 转换为IEnumerator<TTarget>

请注意,此问题不是在寻求有关如何枚举枚举数(使用MoveNextCurrent),或如何将枚举数转换为可枚举(请参阅this discussion),或如何变换枚举数的信息到枚举器(只需在IEnumerable<T> 上调用GetEnumerator()),或者如何将可枚举映射到另一种类型(参见this discussion)。

我提供了我自己提出的答案作为答案,但当然我很高兴听到其他方法。

【问题讨论】:

    标签: c# enumerator


    【解决方案1】:

    我比较喜欢的方法如下。 (也可以将其定义为struct 而不是class,例如以减少堆分配。)

    public class TransformEnumerator<TSource, TTarget> : IEnumerator<TTarget>
    {
        IEnumerator<TSource> SourceEnumerator;
        Func<TSource, TTarget> TransformFunc;
    
        public TransformEnumerator(IEnumerator<TSource> sourceEnumerator, Func<TSource, TTarget> transformFunc)
        {
            SourceEnumerator = sourceEnumerator;
            TransformFunc = transformFunc;
        }
    
        public TTarget Current => TransformFunc(SourceEnumerator.Current);
    
        object IEnumerator.Current => TransformFunc(SourceEnumerator.Current);
    
        public void Dispose()
        {
            SourceEnumerator.Dispose();
        }
    
        public bool MoveNext()
        {
            return SourceEnumerator.MoveNext();
        }
    
        public void Reset()
        {
            SourceEnumerator.Reset();
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是一种方法,使用static class

      public static class TransformEnumerator2<TSource, TTarget>
      {
          public static IEnumerator<TTarget> GetEnumerator(IEnumerator<TSource> source, Func<TSource, TTarget> transformFunc)
          {
              return (IEnumerator<TTarget>)GetEnumerable(source, transformFunc);
          }
      
          private static IEnumerable<TTarget> GetEnumerable(IEnumerator<TSource> source, Func<TSource, TTarget> transformFunc)
          {
              while (source.MoveNext())
                  yield return transformFunc(source.Current);
          }
      }
      

      请注意,GetEnumerable 方法是私有的。在公共 API 中,客户端期望能够多次使用可枚举,但这里的可枚举只能使用一次。然而,一个 Enumerator 应该只被使用一次,因为 Reset 的行为是未定义的,所以这实现了它的目标。

      【讨论】:

        猜你喜欢
        • 2010-12-21
        • 2018-08-01
        • 1970-01-01
        • 2019-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多