Categories
c#

Value Tuples for passing Lists of Key-Value Pairs in C# 7

Prior to C# 7, I have many, many times found myself needing to pass a hard-coded list of key-value pairs to a method, and I’ve had to do it painfully:

void SomeMethod(List<KeyValuePair<string, string>> pairs)
{
// Use the values
}
void Caller() {
// Yuck!
SomeMethod(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("key1", "val1"),
new KeyValuePair<string, string>("key2", "val2")
});
}
view raw program.cs hosted with ❤ by GitHub

We can make this marginally better with a factory function:

// Forgive me for this function name
KeyValuePair<string, string> KVP(string key, string val)
{
return new KeyValuePair<string, string>(key, val);
}
void Caller()
{
// Still pretty bad
SomeMethod(new List<KeyValuePair<string, string>> {
KVP("key1", "val1"),
KVP("key2", "val2")
});
}
view raw program.cs hosted with ❤ by GitHub

Then we can swap the list with an array to improve it a little more:

void SomeMethod(KeyValuePair<string, string>[] pairs)
{
}
void Caller()
{
// Ok, so I hate myself a little less
SomeMethod(new[]
{
KVP("key1", "val1"),
KVP("key2", "val2")
});
}
view raw program.cs hosted with ❤ by GitHub

Finally, we can use ‘params’ on the method so we don’t need to declare an array on the caller:

void SomeMethod(params KeyValuePair<string, string>[] pairs)
{
}
void Caller()
{
// params are great, but I still don't love it.
SomeMethod(
KVP("key1", "val1"),
KVP("key2", "val2")
);
}
view raw program.cs hosted with ❤ by GitHub

Okay, so it’s not too bad, but we still have that factory function which I’m not a fan of.

Value Tuples

Briefly, Value Tuples let you do things like this:

(string value1, string value2) SomeFunc()
{
return ("val1", "val2");
}
void CallerFunction()
{
var result = SomeFunc();
Console.WriteLine(result.value1); // val1
Console.WriteLine(result.value2); // val2
}
view raw program.cs hosted with ❤ by GitHub

You get a small value type containing your two values, that you can declare inline, and access the individual values in the result.

You don’t just have to use these in return types, you can use them anywhere a type definition could be used.

I’ve generally been a little reticent to use this new-ish feature too heavily, because I’m worried about people using them where they should actually be defining types.

That being said…

Making Our Parameters Nicer

In C# 7, now we get to pass those key-value lists the nice way:

void SomeMethod(params (string key, string value)[] pairs)
{
}
void Caller()
{
// Now that's more like it!
SomeMethod(
("key1", "val1"),
("key2", "val2")
);
}
view raw program.cs hosted with ❤ by GitHub

Look at that! No factory function required, we can simply pass in the pairs, just as I’ve wanted to be able to do for years, and it’s super readable.

Just define the array type of your params argument as the tuple you want, and away you go!

I’m still a little wary of Value Tuples generally, but this is definitely a lovely use case for them.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s