13

I was thinking of keeping three pieces of information for each object of a list. So I can create a class with three properties for those three pieces of information, and then create a Collection of that class type... But I was wondering in .NET 3.5 ( and not 4.0 ) have any thing built in for that? for example a dictionary...that one keep two pieces of information for each item, key and value...but I need three. Do we have anything built-in for that?

Bohn
  • 26,091
  • 61
  • 167
  • 254

5 Answers5

20

You can create your own Tuple<T1, T2, T3>:

public class Tuple<T1, T2, T3> : IEquatable<Object>{
    public T1 Item1{
        get;
        set;
    }

    public T2 Item2{
        get;
        set;
    }

    public T3 Item3{
        get;
        set;
    }

    public Tuple(T1 Item1, T2 Item2, T3 Item3){
         this.Item1 = Item1;
         this.Item2 = Item2;
         this.Item3 = Item3;
    }

    public override bool Equals( object obj ) {
        if ( obj == null || (obj as Tuple<T1, T2, T3>) == null ) //if the object is null or the cast fails
            return false;
        else {
            Tuple<T1,T2,T3> tuple = ( Tuple<T1, T2, T3> ) obj;
            return Item1.Equals( tuple.Item1 ) && Item2.Equals(tuple.Item2) && Item3.Equals(tuple.Item3);
        }
    }

    public override int GetHashCode( ) {
        return Item1.GetHashCode( ) ^ Item2.GetHashCode() ^ Item3.GetHashCode();
    }

    public static bool operator == ( Tuple<T1, T2, T3> tuple1, Tuple<T1, T2, T3> tuple2 ) {
        return tuple1.Equals( tuple2 );
    }

    public static bool operator != ( Tuple<T1, T2, T3> tuple1, Tuple<T1, T2, T3> tuple2 ) {
        return !tuple1.Equals( tuple2 );
    }
}
Omar
  • 16,329
  • 10
  • 48
  • 66
  • Cools, just a minor edit to your code: Item2 and Item3 should be of types T2 and T3, prob a copy paste error :) – Bohn Aug 19 '12 at 00:14
  • 3
    I like this solution because as @ChaosPandion points out, it follows what is built into .NET 4.0. When you upgrade you can remove this class altogether. – dana Aug 19 '12 at 00:14
  • 2
    If you're intending to do equality comparisons with the tuple you really need to make it immutable and implement `Equals` and a suitable `GetHashCode`. The tuple as it is defined will give you unexpected results for comparisons. – Enigmativity Aug 19 '12 at 00:32
  • @Enigmativity oh thanks, didn't know that.. I want it to keep a string and two of my own classes so like ... But no "comparison" I will do .. will it still be a problem? Then I am gonna have a ICollection of objects of this Tuple class. – Bohn Aug 19 '12 at 00:37
14

Create your own Triple class:

public class Triple<T,X,Y>
{
   public T t{get;set;}
   public X x{get;set;}
   public Y y{get;set;}
}

It's a clear approach and more manageable than directly using a dictionary, like: Dictionary<Key, KeyValuePair<X,Y>> and other approaches like this.

Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
  • yes, looks like thats the only way to do it, Tuples are for .NET 4.0 – Bohn Aug 19 '12 at 00:04
  • 2
    I would actually follow the convention used in .NET 4 for tuples so you can easily swap them out if you so desire. – ChaosPandion Aug 19 '12 at 00:04
  • @ChaosPandion : thanks, what do you mean by "follow convention used in .NET 4 for tuples" ? – Bohn Aug 19 '12 at 00:06
  • 1
    I think he means "syntax and semantics" rather than "convention". – Enigmativity Aug 19 '12 at 00:08
  • @Saeed:Copy Pasted the Triple class, it gives me errors saying "Member with the same name is already declared. – Bohn Aug 19 '12 at 00:12
  • @BDotA - I believe that it would be beneficial to implement a "Tuple" object in the same manner that it is implemented in .NET 4 so an upgrade means you can remove your version and simplify your libraries. – ChaosPandion Aug 19 '12 at 00:12
  • @ChaosPandion, Implementing whole tuple class is useless, but I'll update my answer with variation of your suggestion. Edit: Someone else did it, so I'll left this as this way. – Saeed Amiri Aug 19 '12 at 00:18
3

The solution of creating a generic tuple class similar to the one that's added in .Net 4 is explained in other answers, but I do feel it's important to state that it might be better to create a small class to semantically represent the data you're storing with meaningful properties. A generic 3-tuple might work now, but you might want to expand on the functionality later.

jwrush
  • 743
  • 7
  • 25
  • You make an important point. Tuple is most appropriate when used internally within a module or a generally small project. – ChaosPandion Aug 19 '12 at 00:25
  • Exactly. A great and natural time for Tuple<...> is when you're implementing an algorithm that's really abstract like a really obscure graph algorithm or math algorithm or something. – jwrush Aug 19 '12 at 00:26
2

If you were using .NET 4, you'd be looking for Tuple<T1,T2,T3>. .NET 3.5 doesn't have a built-in type, but depending on your needs, you can do a Dictionary<T1,Dictionary<T2,Dictionary<T3,bool>>>

saluce
  • 13,035
  • 3
  • 50
  • 67
1

Try Dictionary<Key, Tuple<Object, Object>> or, alternatively, Dictionary<Key, YourClass> where YourClass (which could be a struct, of course), holds the two required pieces of data.

CesarGon
  • 15,099
  • 6
  • 57
  • 85