如何使这个Dictionary TryGetValue代码更具可读性?

时间:2010-06-10 13:20:30

标签: c# .net dictionary trygetvalue

我想测试一个id是否尚未知道,或者,如果已知,则关联值是否已更改。我目前正在使用与此类似的代码,但对于那些不熟悉该模式的人来说很难理解。您是否可以想到一种方法,使其在LOC中保持简短时更具可读性?

string id;
string actual;
string stored;

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

10 个答案:

答案 0 :(得分: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.
}

答案 1 :(得分: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) 
{

}

答案 2 :(得分:3)

包装||的每个部分进入自己的方法或属性,比你可以像这样写

if ( IdIsNew() || IdChanged())

答案 3 :(得分:2)

二重性。

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

不确定它是否更具可读性......但很高兴知道。

答案 4 :(得分: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;
}

答案 5 :(得分:1)

对我而言看起来很好......如果声明,读取就像任何其他2条件一样简单。关于我唯一可能改变的事情是为了提前退出而推翻否定:

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

我根本没有看到任何混淆,从来没有想过它是一个特别麻烦的习语,而且谦卑地建议那些被它迷惑的C#开发者习惯了。这是常见的,简单的,并且给予尽可能多的LOC以应对问题。将其转换为10行代码会使方式过于重要。

如果我经常使用它,那么名为ContainsEqualValue的扩展方法是合适的 - 但我会在扩展方法中使用完全相同的代码。

答案 6 :(得分: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")

答案 7 :(得分: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.
}

答案 8 :(得分:0)

public T GetValue(int id, object actual)
{
  object stored;
 if (someDictionary.TryGetValue (id, out stored) || stored == actual) 
    return stored;
  return new object();
}

答案 9 :(得分:0)

虽然我认识到“try”模式是必要的,但我不喜欢需要“out”参数的实现。函数类似于TryGetValue似乎更有用:

  • 如果key不在字典中,则TryGetDictValue(dictionary,key)返回null
  • 如果key不在字典中,TryGetDictValue(dictionary,key,defaultValue)返回defaultValue
  • TryGetDictValue(dictionary,key,valueReturningDelegate)如果key不在字典中并返回其结果,则调用提供的委托

在每种情况下,结果的返回类型都是字典数据的返回类型。

太糟糕了,没有办法潜入时间机器并使这些东西成为字典的方法。另一方面,可以将它们作为静态函数实现,将字典作为第一个参数。