16

特定のコレクションがあるとします。コレクションを変更することなく、foreachを使用してそのコンテンツを2回ループします。宇宙線を除けば、両方のループで順序が一貫していることが絶対に保証されていますか?

あるいは、HashSet<string>いくつかの要素を持つが与えられた場合、次のコメント行からの出力が等しくなくなる可能性があります。

{
    var mySet = new HashSet<string>();
    // Some code which populates the HashSet<string>

    // Output1
    printContents(mySet);

    // Output2
    printContents(mySet);
}

public void printContents(HashSet<string> set) {
    foreach(var element in set) {
         Console.WriteLine(element);
    }
}

実装が上記の基準を満たさない原因を説明する一般的な回答を得ることができれば、役に立ちます。Dictionary具体的には、とはいえ、List配列に興味があります。

4

4 に答える 4

15

配列の列挙は順序を保証します。

List安定しList<T>た順序を提供することが期待されます(順次インデックス付けされた要素を実装することが期待されるため)。

辞書、HashSetは明示的に順序を保証するものではありません。アイテムを次々に繰り返す2回の呼び出しで、異なる順序でアイテムが返される可能性はほとんどありませんが、保証や期待はありません。特定の順序を期待するべきではありません。

ソートされたバージョンのDictionary/HashSetは、ソート順にアイテムを返します。

他のIEnumerableオブジェクトは、自由に好きなことを実行できます。通常、ユーザーの期待に一致するようにイテレーターを実装します。つまり、明示的な順序が提供されている場合、暗黙的な順序を持つものの列挙は安定している必要があります-安定していることが期待されます。順序を指定しないデータベースへのクエリは、半ランダムな順序でアイテムを返すことが期待されます。

リンクについては、この質問を確認してください。C#のforeachループは、評価の順序を保証しますか?

于 2012-07-27T02:29:38.487 に答える
5

実装するものはすべてIEnumerable<T>、独自の方法で実装します。特定のコレクションが安定性を保証する必要があるという一般的な保証はありません。

特にCollection<T>http://msdn.microsoft.com/en-us/library/ms132397.aspx)を参照している場合は、MSDNリファレンスに順序が一貫しているという特定の保証はありません。

それはおそらく一貫しているでしょうか?はい。書面による保証はありますか?私が見つけることができるというわけではありません。

于 2012-07-27T01:43:27.023 に答える
3

C#コレクションの多くには、コレクションの並べ替えられたバージョンがあります。たとえば、aHashSetはaに対して、 SortedSetaDictionaryはに対してSortedDictionaryです。順序が重要ではないもので作業している場合Dictionary、ループの順序が毎回同じように動作するとは限りません。

于 2012-07-27T01:57:25.297 に答える
0

の例のようにHashSet<T>、チェックするソースコードがあります:HashSet:Enumerator

そのまま、Slot[] set.m_slots配列が繰り返されます。配列オブジェクトは、メソッドTrimExcessInitialize(どちらもコンストラクターでのみ呼び出されます)、、、OnDeserializationおよびSetCapacity(およびによってのみ呼び出されAddIfNotPresentます)でのみ変更されAddOrGetLocationます。

の値は、(、、、、、 )の要素を変更するメソッドでm_slotsのみ変更されます。HashSetClearRemoveAddIfNotPresentIntersectWithSymmetricExceptWith

そうです、セットに何も触れていない場合は、同じ順序で列挙されます。

Dictionary:Enumeratorはまったく同じように機能し、Entry[] entriesそのような非読み取り専用メソッドが呼び出されたときにのみ変更されるを繰り返します。

于 2016-09-05T18:22:45.847 に答える