3

我有一个包含类似内容的类,Dictionary<int, Queue<string>> dict然后我使用TryGetValue

Queue<string> value;
if (!dict.TryGetValue(3, out value))
    throw new MyException("...");

是否有不显式定义值类型的选项,基本上是为了避免重复输入?在 C++ STL 容器中,有一个值 typedefvalue_type可以在这种情况下使用,但我似乎在 C# 中找不到类似的功能。谢谢。

4

4 回答 4

2

如果您为自己定义了一个不错的辅助方法,您可以将类型规范包装起来:

public static class Utility
{
    public static TValue GetValueOrDefault<TKey,TValue>(
        this Dictionary<TKey, TValue> dictionary, 
        TKey key, 
        TValue @default = default(TValue))
    {
        TValue value;
        return dictionary.TryGetValue(key, out value)
                   ? value
                   : @default;
    }
}

请注意,我们仍然必须显式键入将由 填充的值TryGetValue,但是从您的调用者那里您可以说:

var value = dict.GetValueOrDefault(3);    // implicitly typed
if (value == null)
    throw new MyException("...");

请注意,如果null在这种情况下是一个有效值,您将需要其他东西,但可以应用相同的原则 - 使用编译器可以推断泛型方法的类型这一事实来构建一个辅助方法来隐藏显式类型。

于 2012-10-02T11:23:55.387 回答
1

您可以将片段重写为

if (!dict.ContainsKey(3))
    throw new MyException("...");
var value = dict[3];

或者,无耻地窃取并改编自 AakashM 的答案,您可以编写自己的扩展方法来交换TryGetValue参数:

public static V ValueGetTry<K, V>(this Dictionary<K, V> d, K k, out bool found)
{
    V v;
    found = d.TryGetValue(k, out v);
    return v;
}

称为

bool found;
var val = dict.ValueGetTry(3, out found);
if (!found)
    throw new MyException("...");

这应该适用于任何类型的参数,并且只查询一次字典。

于 2012-10-02T11:15:06.313 回答
1

ContainsKey不,如果您这样做并索引到字典中,您可以使用隐式类型变量,如下所示:

var key = 3;
if (!dict.ContainsKey(key)) {
    throw new ...;
}

var value = dict[key];

当然,这会稍微降低效率。但是没有选项可以使用varwith TryGetValue

于 2012-10-02T11:15:30.777 回答
0

现在可以使用 C# 7.0 使用内联out变量

if (!dict.TryGetValue(3, out var value))
    throw new MyException("...");

请参阅https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7#out-variables

于 2019-10-29T12:20:08.483 回答