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: