如何将IEnumerator<KeyValuePair<TKey, TValue>>
转换为包含键值对中的键的IEnumerator<TKey>
?
更一般地说,如果从IEnumerator<TSource>
到IEnumerator<TTarget>
有转换,如何将TSource
转换成TTarget
?
请注意,此问题不是在寻求有关如何枚举枚举数(使用MoveNext
和Current
或如何将枚举数转换为可枚举的信息(请参见this discussion)的信息,或如何将可枚举转换为枚举(只需在GetEnumerator()
上调用IEnumerable<T>
),或如何将可枚举映射为另一种类型(请参见this discussion)。
我提供了自己提出的答案作为答案,但是当然,我很高兴听到其他方法。
答案 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的行为,因此枚举器只能使用一次,因此可以达到其目的。