Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relying on the iteration order of an unmodified HashSet

HashSet<object> myHashSet = new HashSet<object>();

// Iteration 1
foreach (object myObject in myHashSet) { ... }

// Some instructions THAT DO NOT MODIFY myHashSet
...

// Iteration 2
foreach (object myObject in myHashSet) { ... }

Will the objects of myHashSet be enumerated in the same order in both iterations?

like image 673
Numid Avatar asked Dec 25 '22 01:12

Numid


1 Answers

According to the reference source of HashSet (link), the iteration order is predictable in the absence of set modifications.

public bool MoveNext() {
    if (version != set.m_version) {
        throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_EnumFailedVersion));
    }

    while (index < set.m_lastIndex) {
        if (set.m_slots[index].hashCode >= 0) {
            current = set.m_slots[index].value;
            index++;
            return true;
        }
        index++;
    }
    index = set.m_lastIndex + 1;
    current = default(T);
    return false;
}

However unlikely, this could change in future versions of the .NET platforms, or in other implementations. To ensure that the order stays the same, make a list from the set on the first iteration, and use the list for your second iteration:

var myList = myHashSet.ToList();
foreach( var obj myObject in myList) ...
// Some instructions (may or may not modify myHashSet, it no longer matters)
foreach( var obj myObject in myList) ...
like image 103
Sergey Kalinichenko Avatar answered Dec 27 '22 15:12

Sergey Kalinichenko