80

私は最近気づいたDictionary.TryGetValue(TKey key, out TValue value)ので、ディクショナリから値を取得するためのより良いアプローチはどれかについて興味がありました。

私は伝統的に行ってきました:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...

そこにある必要があることを私が知らない限り。

するだけの方が良いですか:

if (myDict.TryGetValue(somekey, out someVal)
    ...

どちらがより良い習慣ですか?一方は他方より速いですか?Try バージョンは、内部で try/catch を「飲み込み」、それをロジックとして使用するため、遅くなると思いますか?

4

4 に答える 4

85

FindEntry は 1 回しか呼び出されないため、TryGetValue の方がわずかに高速です。

どのくらい速くなりますか?手元のデータセットによって異なります。Contains メソッドを呼び出すと、Dictionary は内部検索を実行してインデックスを見つけます。true が返された場合、実際の値を取得するには別のインデックス検索が必要です。TryGetValue を使用すると、インデックスが 1 回だけ検索され、見つかった場合はその値が変数に割り当てられます。

参考:実際にはエラーをキャッチしていません。

それは呼んでいます:

public bool TryGetValue(TKey key, out TValue value)
{
    int index = this.FindEntry(key);
    if (index >= 0)
    {
        value = this.entries[index].value;
        return true;
    }
    value = default(TValue);
    return false;
}

ContainsKey は次のとおりです。

public bool ContainsKey(TKey key)
{
    return (this.FindEntry(key) >= 0);
}
于 2008-12-18T16:53:26.240 に答える
29

実際、TryGetValueの方が高速です。どれくらい速いですか?手元のデータセットによって異なります。containsメソッドを呼び出すと、Dictionaryはそのインデックスを見つけるために内部検索を実行します。trueが返された場合は、実際の値を取得するために別のインデックス検索が必要です。TryGetValueを使用すると、インデックスが1回だけ検索され、見つかった場合は変数に値が割り当てられます。

編集:

わかりました。あなたの混乱を理解しているので、詳しく説明させてください。

ケース1:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];

この場合、FindEntryへの呼び出しは2つあり、1つはキーが存在するかどうかを確認するためのもので、もう1つはキーを取得するためのものです。

ケース2:

myDict.TryGetValue(somekey, out someVal)

この場合、結果のインデックスは同じメソッドで実際に取得するために保持されるため、FindKeyの呼び出しは1つだけです。

于 2008-12-18T17:02:10.467 に答える
0

trygetvalue は次のようなことをしていると思います:

if(myDict.ReallyOptimisedVersionofContains(someKey))
{ 
  someVal = myDict[someKey];
  return true;
}
return false;

したがって、どこにも try/catch がないことを願っています。

本当に便利な方法だと思います。私は通常、1 ~ 2 行のコードを節約できるので、これを使用します。

于 2008-12-18T16:54:37.890 に答える