C#类是IEnumerable,同时是IEnumerator。这有什么问题? [英] C# Class is IEnumerable AND an IEnumerator at the same time. What are the issues with this?
问题描述
我有一个名为GenericPermutations的类,它既可枚举又可枚举。它的工作是获取对象的有序列表,并依次遍历对象的每个排列。
I have a class called GenericPermutations that is both enumerable and an enumerator. Its job is to take an ordered list of objects and iterate through each permutation of them in order.
例如,此类的整数实现可以遍历以下内容:
Example, an integer implemenation of this class could iterate through the following:
GenericPermutations<int> p = new GenericPermutations<int>({ 1, 2, 3 });
p.nextPermutation(); // 123
p.nextPermutation(); // 132
p.nextPermutation(); // 213
// etc.
因此,在它包含一个您可以列举的事物的清单。它也是一个枚举器,因为它的工作涉及寻找下一个排列。
So its enumerable in the sense that it contains a 'list' of things you can enumerate over. It's also an enumerator, because its job involves finding the next permutation.
问题:我目前正在尝试将IEnumerator和IEnumerable与之集成类,在我看来,应该两者兼有(而不是将子类用作IEnumerable)。到目前为止,我通过在 GetEnumerator
方法中传递一个新的GenericPermutation对象来尝试从中获取两个枚举数,从而避免了该问题。
THE ISSUE: I am currently trying to integrate IEnumerator and IEnumerable with this class, and it seems to me like it should be both (rather than using a sub class as the IEnumerable). Thus far I have avoided the issue with trying to get two enumerators from it by passing a new GenericPermutation object in the GetEnumerator
method.
这是个坏主意吗?
推荐答案
通过使用 IEnumerable的通用版本减少您的困惑(?)
和 IEnumerator
。
可枚举的排列是 IEnumerable< IEnumerable< T>
。因此,您可能会遇到类似
A permutation enumerable is IEnumerable<IEnumerable<T>>
. So you might have something like
IEnumerable<IEnumerable<T>> GetPermutations(IEnumerable<T> sequence)
{
return new Permuter<T>(sequence);
}
和
public class Permuter<T> : IEnumerable<IEnumerable<T>> { ... }
此外,我已经看到了不止一种情况,一个类型同时实现了两种 IEnumerable< T>
和 IEnumerator< T>
;它的GetEnumerator方法只是返回该值;
。
Furthermore, I've seen more than one case where a single type implemented both IEnumerable<T>
and IEnumerator<T>
; its GetEnumerator method was simply return this;
.
我认为这样的类型需要是一个结构,尽管,因为如果它是一个类,那么如果在第一次枚举完成之前第二次调用GetEnumerator(),就会遇到各种各样的问题。
I think such a type would need to be a struct, though, because if it were a class you'd have all sorts of problems if you called GetEnumerator() a second time before the first enumeration was completed.
编辑:使用permuter
Consuming the permuter
var permuter = GetPermutations(sequence);
foreach (var permutation in permuter)
{
foreach (var item in permutation)
Console.Write(item + "; ");
Console.WriteLine();
}
假设输入序列为{1,2,3},则输出为
Assuming the input sequence is { 1, 2, 3 }, the output is
1; 2; 3;
1; 3; 2;
2; 1; 3;
2; 3; 1;
3; 1; 2;
3; 2; 1;
编辑:
在这里,
public class Permuter<T> : IEnumerable<IEnumerable<T>>
{
private readonly IEnumerable<T> _sequence;
public Permuter(IEnumerable<T> sequence)
{
_sequence = sequence;
}
public IEnumerator<IEnumerable<T>> GetEnumerator()
{
foreach(var item in _sequence)
{
var remaining = _sequence.Except(Enumerable.Repeat(item, 1));
foreach (var permutation in new Permuter<T>(remaining))
yield return Enumerable.Repeat(item, 1).Concat(permutation);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
这篇关于C#类是IEnumerable,同时是IEnumerator。这有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!