【问题标题】:"Verbose Dictionary" in C#, 'override new' this[] or implement IDictionaryC# 中的“详细字典”,“覆盖新的”this[] 或实现 IDictionary
【发布时间】:2010-04-27 05:33:48
【问题描述】:

我想要的只是一本字典,它告诉我找不到哪个键,而不仅仅是说The given key was not present in the dictionary

我曾短暂考虑过用override new this[TKey key] 做一个子类,但觉得它有点笨拙,所以我已经实现了 IDictionary 接口,并将所有内容直接传递给内部字典,唯一的附加逻辑在索引器:

public TValue this[TKey key]
{
    get
    {
        ThrowIfKeyNotFound(key);
        return _dic[key];
    }
    set
    {
        ThrowIfKeyNotFound(key);
        _dic[key] = value;
    }
}
private void ThrowIfKeyNotFound(TKey key)
{
    if(!_dic.ContainsKey(key))
        throw new ArgumentOutOfRangeException("Can't find key [" + key + "] in dictionary");
}

这是正确/唯一的方法吗?更新 this[] 真的有那么糟糕吗?

【问题讨论】:

    标签: c# dictionary coding-style


    【解决方案1】:

    听起来很适合扩展方法:

    public static class SomeUtilClass {
        public static TValue VerboseGetValue<TKey, TValue>(
            this IDictionary<TKey, TValue> data, TKey key)
        {
            TValue result;
            if (!data.TryGetValue(key, out result)) {
                throw new KeyNotFoundException(
                    "Key not found: " + Convert.ToString(key));
            }
            return result;
        }
    }
    

    这将在您调用 VerboseGetValue 时适用于您现有的所有词典,例如:

        var data = new Dictionary<int, string> { { 123, "abc" } };
        Console.WriteLine(data.VerboseGetValue(123));
        Console.WriteLine(data.VerboseGetValue(456));
    

    【讨论】:

    • 我很高兴用户 #1 和 #2 位于地球的右侧 :)
    【解决方案2】:

    与其在接触底层字典之前执行 ContainsKey 并检查键是否存在,不如这样做

    get {
        try {
            return _dic[key];
        }
        catch (ArgumentOutOfRangeException) {
            throw new ArgumentOutOfRangeException(......);
        }
    }
    

    这样,您只需为失败案例中的额外检查付费 - 希望更常见的成功案例无需进行额外的字典查找。这对 get 有好处,但 set 更难,因为 set 的默认行为是始终有效。如果您不希望这样做,则需要先检查密钥是否存在。

    【讨论】:

    • +1 异常处理程序是处理异常情况的最佳方式。这就是他们的目的。 :)
    • @Stewart 除非我弄错了,否则System.Collections.Generic.Dictionary 在找不到键时不会在索引器中引发错误,而是会以静默方式添加新值。不过,您的方法仍然适用于吸气剂。
    • @GeorgesDupéron - 你说得很对。这仅适用于 get 情况。我将修改示例。对于设置的情况,额外的检查是不可避免的。
    【解决方案3】:

    如果您想这样做,您将不得不以一种或另一种方式推出自己的产品。但我要问你为什么要这样做?

    【讨论】:

    • 好吧,我想我在问题中说了为什么。但是,与其从进行设置的人那里收到一封邮件说“我弄错了哪个值?”,我更希望他能够自己修复它。
    猜你喜欢
    • 1970-01-01
    • 2016-07-05
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2010-10-29
    相关资源
    最近更新 更多