C#Class同时是IEnumerable和IEnumerator.这有什么问题?

我有一个名为GenericPermutations的类,它既是可枚举的又是枚举器.它的工作是获取一个有序的对象列表,并按顺序迭代它们的每个排列.

例如,此类的整数实现可以迭代以下内容:

GenericPermutations<int> p = new GenericPermutations<int>({ 1,2,3 });
p.nextPermutation(); // 123
p.nextPermutation(); // 132
p.nextPermutation(); // 213
// etc.

所以它的可枚举性就是它包含了你可以枚举的事物的“列表”.它也是一个普查员,因为它的工作涉及寻找下一个排列.

问题:我目前正在尝试将IEnumerator和IEnumerable与这个类集成,在我看来它应该是两者(而不是使用子类作为IEnumerable).到目前为止,我已经避免了通过在GetEnumerator方法中传递新的GenericPermutation对象来尝试从中获取两个枚举器的问题.

这是一个坏主意吗?还有什么我应该考虑的吗?

解决方法

通过使用IEnumerable和IEnumerator的通用版本减少您的混淆(?).

可枚举的排列是IEnumerable< IEnumerable< T>>.所以你可能有类似的东西

IEnumerable<IEnumerable<T>> GetPermutations(IEnumerable<T> sequence)
{
    return new Permuter<T>(sequence);
}

public class Permuter<T> : IEnumerable<IEnumerable<T>> { ... }

此外,我已经看到不止一种情况,其中单个类型实现了IEnumerable< T>和IEnumerator< T&gt ;;它的GetEnumerator方法只是返回这个; 我认为这样的类型需要是一个结构,因为如果它是一个类,如果你在第一个枚举完成之前第二次调用GetEnumerator(),你就会遇到各种各样的问题. 编辑:消费permuter

var permuter = GetPermutations(sequence);
foreach (var permutation in permuter)
{
    foreach (var item in permutation)
        Console.Write(item + "; ");
    Console.WriteLine();
}

假设输入序列是{1,3},则输出为

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&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...