Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# 3.0 Tuple Equivalents (for poor men)

Tags:

tuples

c#-3.0

I find myself occasionally in C# 3.0 looking for ways to simulate the notion of a tuple. Over time I've had various "poor man's" implementations, here are a few of them:

Basic Object Array:

object[] poorTuple = new object[]{foo,bar,baz}; // basic object array

More Strongly Typed, HoHoHo...

KeyValuePair<TypeA, KeyValuePair<TypeB, TypeC>> poorTuple;

Implementing a class that can use type inference (lifted from Functional Programming for the Real World)

public static class Tuple{
  public static Tuple<T1, T2> Create<T1 foo, T2 bar>{
    return new Tuple<T1, T2>(foo, bar);
  }
}
// later: 
var data = Tuple.Create("foo", 42);

Questions:

  1. Any other ways to have a poor man's tuple in C# 3.0 (or language of choice that lacks the data structure).

  2. What is the best way to get a tuple in C# 3.0 - if anyone has a library recommendation it is welcome.

  3. At what point (yes, generalize for me) does it make sense to create a specific type rather than something like a list or tuple? (looking for rules of thumb)

like image 839
t3rse Avatar asked Nov 30 '09 21:11

t3rse


3 Answers

You can create anonymous types which function similarly to tuples, except with useful names:

var itemsWithChildCounts 
    = myObjects.Select(x => new { Name = x.Name, Count = x.Children.Count() });
like image 53
Mark Byers Avatar answered Sep 24 '22 19:09

Mark Byers


Here is the code for a generic tuple taken from Bill Wagner's article in the April 2007 edition of Visual Studio Magazine.

public struct Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
{
    private readonly T1 first;
    public T1 First
    {
        get { return first; }
    }

    private readonly T2 second;
    public T2 Second
    {
        get { return second; }
    } 

    public Tuple(T1 f, T2 s)
    {
        first = f;
        second = s;
    }

    #region IEquatable<Tuple<T1,T2>> Members
    public bool Equals(Tuple<T1, T2> other)
    {
        return first.Equals(other.first) && 
            second.Equals(other.second);
    }

    public override bool Equals(object obj)
    {
        if (obj is Tuple<T1, T2>)
            return this.Equals((Tuple<T1, T2>)obj);
        else
            return false;
    }

    public override int GetHashCode()
    {
        return first.GetHashCode() ˆ second.GetHashCode();
    }
    #endregion
}
like image 28
Matt Davis Avatar answered Sep 25 '22 19:09

Matt Davis


For 1 - 2: I prefer implementing your own tuple class. The implementation you stole is a decent one. It should work well.

For 3: Here's my rule of thumb - As soon as you're going to reuse this functionality in multiple methods (with the same types having the same meaning), or if you use it in any public API, I think it's time to implement a "real" class with your specific types.

like image 33
Reed Copsey Avatar answered Sep 25 '22 19:09

Reed Copsey