C#类是IEnumerable,同时是IEnumerator。这有什么问题? [英] C# Class is IEnumerable AND an IEnumerator at the same time. What are the issues with this?

查看:94
本文介绍了C#类是IEnumerable,同时是IEnumerator。这有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆