Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way of using a pair (triple, etc) of values as one value in C#?

That is, I'd like to have a tuple of values.

The use case on my mind:

Dictionary<Pair<string, int>, object>

or

Dictionary<Triple<string, int, int>, object>

Are there built-in types like Pair or Triple? Or what's the best way of implementing it?

Update There are some general-purpose tuples implementations described in the answers, but for tuples used as keys in dictionaries you should additionaly verify correct calculation of the hash code. Some more info on that in another question.

Update 2 I guess it is also worth reminding, that when you use some value as a key in dictionary, it should be immutable.

like image 895
Max Galkin Avatar asked Sep 19 '08 13:09

Max Galkin


4 Answers

Builtin Classes

In certain specific cases, the .net framework already provides tuple-like classes that you may be able to leverage.

Pairs and Triples

The generic System.Collections.Generic.KeyValuePair class could be used as an adhoc pair implementation. This is the class that the generic Dictionary uses internally.

Alternatively, you may be able to make do with the System.Collections.DictionaryEntry structure that acts as a rudimentary pair and has the advantage of being available in mscorlib. On the down side, however, is that this structure is not strongly typed.

Pairs and Triples are also available in the form of the System.Web.UI.Pair and System.Web.UI.Triplet classes. Even though theses classes live in the the System.Web assembly they might be perfectly suitable for winforms development. However, these classes are not strongly typed either and might not be suitable in some scenarios, such as a general purposed framework or library.

Higher order tuples

For higher order tuples, short of rolling your own class, there may not be a simple solution.

If you have installed the F# language, you could reference the FSharp.Core.dll that contains a set of generic immutable Microsoft.Fsharp.Core.Tuple classes up to generic sextuples. However, even though an unmodified FSharp.Code.dll can be redistributed, F# is a research language and a work in progress so this solution is likely to be of interest only in academic circles.

If you do not want to create your own class and are uncomfortable referencing the F# library, one nifty trick could consist in extending the generic KeyValuePair class so that the Value member is itself a nested KeyValuePair.

For instance, the following code illustrates how you could leverage the KeyValuePair in order to create a Triples:

int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;

KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
   new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;

This allows to extend the class to any arbitrary level as is required.

KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string> quadruple =
    new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>();
KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string> quintuple =
    new KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string>();

Roll Your Own

In other cases, you might need to resort to rolling your own tuple class, and this is not hard.

You can create simple structures like so:

struct Pair<T, R>
{
    private T first_;
    private R second_;

    public T First
    {
        get { return first_; }
        set { first_ = value; }
    }

    public R Second
    {
        get { return second_; }
        set { second_ = value; }
    }
}

Frameworks and Libraries

This problem has been tackled before and general purpose frameworks do exist. Below is a link to one such framework:

  • Tuple Library by Michael L Perry.
like image 168
2 revs Avatar answered Nov 14 '22 14:11

2 revs


public struct Pair<T1, T2>
{
    public T1 First;
    public T2 Second;
}

public struct Triple<T1, T2, T3>
{
    public T1 First;
    public T2 Second;
    public T3 Third;
}
like image 37
Timothy Carter Avatar answered Nov 14 '22 15:11

Timothy Carter


Fast-forward to 2010, .NET 4.0 now supports n-tuples of arbitrary n. These tuples implement structural equality and comparison as expected.

like image 11
Mauricio Scheffer Avatar answered Nov 14 '22 15:11

Mauricio Scheffer


Pair and Triplet are existing classes in .net see msdn:

Triplet

Pair

I recently came across them, while playing around with viewstate decoding

like image 9
Adam Vigh Avatar answered Nov 14 '22 15:11

Adam Vigh