c# - HashSet 枚举器有什么作用?

标签 c# collections iterator hashset enumerator

我不习惯写C#代码,只会写Java和Python。 现在我找到了一些仅在 C# 中可用的算法的代码示例。 有一个结构我不明白,它是枚举器。

HashSet<Node>.Enumerator enumerator = hashSet.GetEnumerator();
enumerator.MoveNext();
Item next = enumerator.Current;

所以Item是存储在HashSethashSet中的数据类型。这是否等于 for 循环迭代 HashSet 或者如何将其转换为 python 或 java?

最佳答案

GetEnumerator()方法以 C# 中的某些数据结构形式呈现,例如 List , Set等等。它可以进行迭代。实际上,foreach内部使用它。


foreach语句是迭代某些数据结构的元素。一个foreach当满足以下所有条件时即可使用:

  • 数据结构实现 IEnumerable (这是为了 满足泛型之前的遗留代码)或 IEnumerable<T>对于一些 类型T .
  • 您不需要知道数据结构中的位置 单个元素。

例如,string类同时实现 IEnumerableIEnumerable<Char> .

IEnumerable<T>接口(interface)隐含的数据结构需要两个方法:

  • public IEnumerator<T> GetEnumerator()
  • IEnumerator IEnumerable.GetEnumerator()

需要后一种方法只是因为 IEnumerable<T>IEnumerable 的子类型,并且该接口(interface)需要 GetEnumerator返回非泛型的方法 IEnumerator 。这两个方法应该返回相同的对象;因此,因为IEnumerator<T>也是 IEnumerator 的子类型,这个方法可以简单调用第一个方法:

System.Collections.IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

如您所见,IEnumerable.GetEnumerator()方法返回对另一个名为 System.Collections.IEnumerator 的接口(interface)的引用。该接口(interface)提供了基础结构,允许调用者遍历 IEnumerable 兼容容器包含的内部对象:

public interface IEnumerator
{
   bool MoveNext (); // Advance the internal position of the cursor.
   object Current { get;} // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.
}

让我们举例说明。

public class PowersOfThree : IEnumerable<int>
{      
    public IEnumerator<int> GetEnumerator()
    {
        return new PowersOfThreeEnumerator();
    }       
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }       
}


internal class PowersOfThreeEnumerator : IEnumerator<int>
{
    private int index = 0;

    public int Current
    {
        get { return (int)System.Math.Pow(3, index); }
    }

    object System.Collections.IEnumerator.Current
    {
        get { return Current; }
    }

    public bool MoveNext()
    {
        index++;

        if (index > 10)
            return false;
        else
            return true;
    }

    public void Reset()
    {
        index = 0;
    }

    public void Dispose()
    {
    }
}

public class Test 
{
    public static void Main(string[] str)
    {
        var p2 = new PowersOfThree();
        foreach (int p in p2)
        {
            System.Console.WriteLine(p);
        }
    }
}

Current方法返回相同的元素,直到 MoveNext方法被调用。初始索引为0每个MoveNext方法从 1 增加索引到 10(含 10),则返回 false 。当枚举器处于此位置时,后续调用 MoveNext还返回false .

你看到 Current 发生了什么吗?当MoveNext返回false ?可以设置Current再次到集合的第一个元素? 如果您不重新实例化新的枚举器,则不会。

关于c# - HashSet 枚举器有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67859912/

相关文章:

c++ - 用于枚举图中所有节点值的伪迭代器操作

c++ - 比较迭代器,C++

c# - 什么是NullReferenceException,如何解决?

c# - 代码分析警告CA1506 : "Avoid excessive class coupling"如何解决

c# - 带有部分 View 的 ajax 选项卡式 Pane 中的 IpagedList 无法正确呈现

Java 8 将 BiFunction 应用于两个不同对象的列表

Python defaultdict 和 lambda

iterator - "Cannot assign to immutable value"尝试分配给字符串+角色时

c# - 本土化。扩展 ASP.NET Resx 资源提供程序

Swift 函数查找集合中与谓词匹配的第一个元素?