6

IDがまだ知られていないかどうか、または既知の場合は関連付けられた値が変更されているかどうかをテストしたいと思います。私は現在これに似たコードを使用していますが、パターンに慣れていない人には理解しにくいです。LOC を短く保ちながら、読みやすくする方法を考えられますか?

string id;
string actual;
string stored;

if (!someDictionary.TryGetValue (id, out stored) || stored != actual) {
    // id not known yet or associated value changed.
}
4

10 に答える 10

5

適切な名前で拡張メソッドを作成できます。

public static class Utility
{
    public static bool ValueChangedOrUnknown(this Dictionary<string, string> dictionary, string id, string actual)
    {
        string stored = null;
        return (!dictionary.TryGetValue(id, out actual) || stored != actual);
    }
}

後で使用できます

string id;
string actual;

if (someDictionary.ValueChangedOrUnknown(id, actual) {
    // id not known yet or associated value changed.
}
于 2010-06-10T13:38:25.447 に答える
4

したがって、おそらくそれを分割して、意味のある名前を付けます。これはもっと読むべきですが、コメントで多くを言う必要はありません:

bool isKnown = someDictionary.TryGetValue (id, out stored);
// can only change when it is known
bool valueChanged = isKnown && stored != actual;

// quite self-explanatory, isn't it?
if (!isKnown || valueChanged) 
{

}
于 2010-06-10T13:24:06.480 に答える
3

|| の各部分をラップします。このように書くことができるよりも、独自のメソッドまたはプロパティに

if ( IdIsNew() || IdChanged())
于 2010-06-10T13:25:18.193 に答える
2

二元性。

if (!(someDictionary.TryGetValue (id, out stored) && stored == actual)) ...

読みやすいかどうかはわかりませんが、知っておくとよいでしょう。

于 2010-06-10T13:24:11.783 に答える
1

私は新しい方法を好みます:

public bool ShouldSetValue(Dictionary someDictionary, object id,object actualValue)
{
    string stored;

    if (someDictionary.TryGetValue (id, out stored)) 
    {
        if (stored != actualValue)
            return true;
    }
    else
    {
        return true;
    }
}

次に、既存の方法では、次のようにします。

if (ShouldSetValue(someDictionary,id,actual))
{
     someDictionary[id]=actual;
}
于 2010-06-10T13:29:50.727 に答える
1

それは私には問題ないように見えます...他の2つの条件ifステートメントと同じくらい簡単に読めます。私が変更できる唯一のことは、早期終了のために否定を反転することです。

if (someDictionary.TryGetValue(id, out stored) && stored == actual) {
    return;
}
// store new value

特に厄介なイディオムだと思ったことはありません。混乱している C# 開発者は、それに慣れることを謙虚に提案します。それは一般的で簡潔で、問題に値するだけ多くの LOC を与えます。それを 10 行のコードにすると、あまりにも重要になります。

私が頻繁に使用する場合は、次のような名前の拡張メソッドContainsEqualValueが適切ですが、拡張メソッドでは、あなたが持っているのとまったく同じコードを使用します。

于 2010-06-10T14:07:22.530 に答える
0

これを繰り返し行う必要があり、長くて醜い場合は、ロジックを別のクラスに抽象化し、拡張メソッドを使用してください。

public static class DictionaryExtensions
{
    public static DictionaryChecker<TKey,TValue> contains<TKey,TValue>(this IDictionary<TKey,TValue> dictionary, TValue value)
    {
        return new DictionaryChecker<TKey,TValue>(value, dictionary);
    }
}

public class DictionaryChecker<TKey,TValue>
{
    TValue value;
    IDictionary<TKey,TValue> dictionary;

    internal DictionaryChecker(TValue value, IDictionary<TKey, TValue> dictionary)
    {
        this.value = value;
        this.dictionary = dictionary;
    }

    public bool For(TKey key)
    {
        TValue result;
        return dictionary.TryGetValue(key, out result) && result.Equals(value);
    }
}

次に、コードを次のように置き換えます。

if(!someDictionary.contains(actual).For(id)){
    // id not known yet or associated value changed.
}
于 2010-06-10T13:44:05.140 に答える
0
public T GetValue(int id, object actual)
{
  object stored;
 if (someDictionary.TryGetValue (id, out stored) || stored == actual) 
    return stored;
  return new object();
}
于 2010-06-10T14:37:38.347 に答える
0

拡張メソッドは巧妙です:

public static class DictionaryExtensions
{
    public static bool ShouldAddValue<TKey, TValue>(this Dictionary<TKey, TValue> someDictionary, TKey id, TValue actual)
    {
        TValue stored;
        return (!someDictionary.TryGetValue(id, out stored) || !stored.Equals(actual)); 
    }
}

使用法:

someDictionary.ShouldAddValue("foo", "bar")
于 2010-06-10T13:41:46.877 に答える
0

「try」パターンが必要であることは認識していますが、「out」パラメーターを必要とする実装は嫌いです。TryGetValue に似た関数を使用すると、はるかに便利に思えます。

  • キーが辞書にない場合、TryGetDictValue(dictionary, key) は null を返します
  • キーがディクショナリにない場合、TryGetDictValue(dictionary, key, defaultValue) は defaultValue を返します
  • TryGetDictValue(dictionary, key, valueReturningDelegate) は、キーが辞書にない場合に提供されたデリゲートを呼び出し、その結果を返します

いずれの場合も、結果の戻り値の型はディクショナリのデータの型になります。

残念ながら、タイムマシンに忍び込んで、そんなものを辞書のメソッドにする方法はありません。一方、辞書を最初のパラメーターとして取る静的関数としてそれらを実装することもできます。

于 2010-06-29T20:32:38.367 に答える