Using List of more complex generic type

  • Thread starter Thread starter K Viltersten
  • Start date Start date
K

K Viltersten

Suppose that you used List<int> and
also List<double>. Then you realize
that they corespond to each other.
I'd like to declare something along
the lines of

List<int, double>

which can, of course be done by
creating a class IntDouble with two
members. However, i wonder if
there's a smoother solution. Maybe
already existing class?
 
K Viltersten said:
Suppose that you used List<int> and
also List<double>. Then you realize
that they corespond to each other. I'd like to declare something along the
lines of

List<int, double>

which can, of course be done by creating a class IntDouble with two
members. However, i wonder if there's a smoother solution. Maybe
already existing class?

If the int content is unique, then Dictionary<int, double>. Otherwise
 
Suppose that you used List<int> and
also List<double>. Then you realize
that they corespond to each other.
I'd like to declare something along
the lines of

  List<int, double>

which can, of course be done by
creating a class IntDouble with two
members. However, i wonder if
there's a smoother solution. Maybe
already existing class?

What's wrong with List<myClass> where myClass is a class with two
properties, one int and one double?
 
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

Dictionary<Tkey,TType> is probably what you want.
 
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).

On a side note, there was also a little-known library TR for the ECMA
CLI standard that included a couple utility classes, Tuple being among
them. It has a reference implementation with source code. Have a look:

http://www.ecma-international.org/publications/techreports/E-TR-089.htm
 
List said:
What's wrong with List<myClass> where
myClass is a class with two properties,
one int and one double?

Nothing. I just thought it could give a
nicer impression than

List<IntDouble>...

Also, we could skip the time it takes to
create in instance of that class but
that's not really an issue, i know.
 
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.

Well, how about the relation x-values and
y-values for, say, different registers (indexed
by x) receiving different amounts of money
(measured by y)? Isn't that a relation, still not
being one-to-one?
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.

But we'll still have to declare them ourselves,
like you showed in the examples below, right?

Also, i assume it will be possible to create
tripples, quadrupples etc. that way. Will it?

I have the pleasure to pick my own tools,
since it's a hobby project of mine. Perhaps i
could switch to C#4.0. I assume it can be run
under VS2008, of course?
 
My two cents: if there _really_ is a key/value relationship between the
There's obviously _some_ relationship. That's where the question started.
The question is, do you have values that can be selected by a key.

No, i don't. The same register can recieve two different
deposits and those are to be treated individually. I.e.,
the situation of:

2$ into register D + 3$ into register D

is NOT equivalent to

5$ into register D

However, i understand your point and i agree that more
often than expected, we can use Dictionary, even
though it doesn't feel obvious.
The fact that you used the word "indexed by" in your post strongly
suggests a Dictionary is in fact a good choice for this situation.

The registers are indexed but not the deposits. In fact,
the pair register-deposit amount will still not be unique
and there's additional info connected to it... :)
If you want to use something like that now, you can put one of the
implementations I posted...

Hmm... The reason for me asking is that the first piece
doesn't work. First i thought it was only that you used
one comma character to many (in the constructor) but
after that, i still get a nag as follows.

"The 'this' object cannot be used before all of its
fields are assigned to"

Do i miss something?
 
Sorry for the confusion. You can either use the immutable version, or
modify the immutable version to allow for mutable properties (i.e.
add a "set" method, and remove the "readonly" from the backing
fields).

Or use public fields if you want mutability. This is a struct, after all,
which is just a lightweight data container, typically without much in the
way of behavior or encapsulation.
 
However, i understand your point and i agree that more
Perhaps what you want is a Dictionary<int, List<double>>.
Or even Dictionary<int, Register> where "Register" refers
to some hypothetical class in your code that represents a
register, in which the list of values along with other
register-specific data is stored.

I'll think fo something. Thanks.
Sorry. One of the risks of typing uncompiled, untested
code into a newsgroup post. :)

That's totally fine. C.f. my other post...
I think that an immutable Tuple is better anyway, so I'll
advise that if you do use a Tuple implementation, you
go with the immutable version.

I agree and i've already done that. Thanks!
 
Back
Top