Peter Vrabel
Peter Vrabel

Reputation: 372

Dictionary and getting a type of value

I have a class that contains something like this Dictionary<int, Queue<string>> dict and then I use TryGetValue:

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

Is there an option not to explicitly define the value type, basically to avoid duplicity of typing it? In C++ STL containers, there is a value typedef value_type which can be used in such cases but I can't seem to find similar feature in C#. Thanks.

Upvotes: 3

Views: 1082

Answers (4)

Michael Parker
Michael Parker

Reputation: 8430

This is now possible with C# 7.0 using inline out variables

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

See https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7#out-variables

Upvotes: 0

Rawling
Rawling

Reputation: 50204

You can re-write your fragment as

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

Or, shamelessly stolen and adapted from AakashM's answer, you could write your own extension method to swap the TryGetValue parameters around:

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;
}

called as

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

This should work for any type arguments, and only queries the dictionary once.

Upvotes: 1

AakashM
AakashM

Reputation: 63378

If you define yourself a nice helper method, you can wrap up the type specification:

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;
    }
}

Notice here we still have to explicitly type the value that's going to be populated by TryGetValue, BUT from your caller you can just say:

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

Note that if null is a valid value in this context, you'll need something else, but the same principle could be applied - use the fact that the compiler can infer types for generic methods to build a helper method to hide the explicit typing.

Upvotes: 2

Jon
Jon

Reputation: 437854

No. You could have used an implicitly typed variable if you did ContainsKey and index into the dictionary, as in:

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

var value = dict[key];

Of course this would be slightly less efficient. But there is no option to use var with TryGetValue.

Upvotes: 1

Related Questions