My two cents: if there _really_ is a key/value relationship between the
two _and_ there is functional need to be able to quickly map from key to
value (pretty typical when the relationship exists in the first place),
then Dictionary is the way to go.
Otherwise, using the KeyValuePair struct is inappropriate. Just my
opinion, of course, but the KeyValuePair struct implies a relationship
that, if it holds, means one probably ought to be using the Dictionary
anyway, and if it doesn't hold, is misleading in the code (because it's
implying something that's not true).
For data elements that are more just equal partners, IMHO a different type
is called for. Unfortunately, no predefined type for this purpose exists
in C# yet. But, .NET 4.0 will have a series of "Tuple" generic types.
Some people think it's a pretty good idea:
http://code.logos.com/blog/2008/11/tuples_in_net.html
Others, not so much:
http://roy-peled.blogspot.com/2008/10/tuples-are-evil..html
The first link includes a sample implementation of a Tuple struct (usable
for pre-.NET 4.0 code). If you don't need the equality features, then
something like this would even do:
struct Tuple<T1, T2>
{
public T1 First { get; set; }
public T2 Second { get; set; }
public Tuple(T1 t1, T2, t2)
{
First = t1;
Second = t2;
}
}
If you want it immutable (a very good idea), then:
struct Tuple<T1, T2>
{
public T1 First { get { return _t1; } }
public T2 Second { get { return _t2; } }
public Tuple(T1 t1, T2 t2)
{
_t1 = t1;
_t2 = t2;
}
private readonly T1 _t1;
private readonly T2 _t2;
}
That said, it seems to me that a "Tuple" type fills a very specific
purpose, fitting in between anonymous types (where you only use them
locally, but would like meaningful property names) and named types (where
you want to expose the data structure outside a method, but would like
meaningful property names and/or a meaningful type name).
If you have a situation where you simply need to group two or more values
of a given type in a single data structure, it's obvious from the context
what the group of values and each individual member is, _and_ you need to
be able to pass that group around outside a single method, then a "Tuple"
type very well might be appropriate. For example, if the most expressive
name you could come up with for the usage is "IntDouble" with the two
properties being named "Int" and "Double", then a "Tuple<int, double>" is
probably appropriate.
If not, just go ahead and write a meaningful named type. And name the
type something more informative than "IntDouble", with properties more
informative than "Int" and "Double".
Pete