将枚举器(不可枚举)类型映射到另一种类型的枚举器

时间:2019-01-04 22:22:38

标签: c# enumerator

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

更一般地说,如果从IEnumerator<TSource>IEnumerator<TTarget>有转换,如何将TSource转换成TTarget

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

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

2 个答案:

答案 0 :(得分:0)

我更喜欢的方法如下。 (例如,为了减少堆分配,也可以将其定义为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();
    }
}

答案 1 :(得分:0)

这是使用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中,客户端希望能够多次使用枚举,但此处的枚举只能使用一次。但是,由于未定义Reset的行为,因此枚举器只能使用一次,因此可以达到其目的。