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

maf*_*afu 6 .net c# 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.
}
Run Code Online (Sandbox Code Playgroud)

max*_*max 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

以后你可以使用

string id;
string actual;

if (someDictionary.ValueChangedOrUnknown(id, actual) {
    // id not known yet or associated value changed.
}
Run Code Online (Sandbox Code Playgroud)

  • +1。我讨厌“ out”参数,通常使用扩展方法包装对TryGetValue的任何访问(例如,使用TryGetValueOrDefault直接返回条目,如果找不到该条目,则返回null或0)。 (2认同)

Mar*_*ett 1

它对我来说看起来不错...读起来和任何其他 2 个条件 if 语句一样简单。我唯一可能改变的就是翻转提前退出的否定:

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

我根本没有看到它有任何混乱,从来没有认为它是一个特别麻烦的习惯用法,并谦虚地建议那些被它困惑的 C# 开发人员习惯它。它很常见、简洁,并且为问题提供了尽可能多的 LOC。把它变成10行代码就可以了重要了。

如果我经常使用它,一个名为类似名称的扩展方法ContainsEqualValue将是合适的 - 但我会在扩展方法中使用与您完全相同的代码。

  • 它与任何 2 条件语句不太一样,因为它需要预先声明“out”参数。“…习惯它?” 这并不是说开发人员“困惑”,*本身*。即使是从左到右阅读的资深程序员也必须来回跳动才能阅读本文,并在这样做时在头脑中处理多个元素。这不是一个“困难”的任务,但也不是自然的。这在某种程度上是程序代码,并且引入了重复和错误的机会。可读性是一个合理的关注点,而带有“bool”结果的“TryGetValue”在语义上是很弱的。 (2认同)