Tutorial :Why Tuple's items are ReadOnly?


I was thinking to use Tuple class to store 2 integer information (StartAddress, EndAddress) I need in my program.

But I discover that Tuple items are ReadOnly, so if I need to set a value for an item, I need to re-instantiate a Tuple.

What is the reason behind this design decision?


Tuples originated in functional programming. In (purely) functional programming, everything is immutable by design - a certain variable only has a single definition at all times, as in mathematics. The .NET designers wisely followed the same principle when integrating the functional style into C#/.NET, despite it ultimately being a primarily imperative (hybrid?) language.

Note: Though I suspect the fact that tuples are immutable doesn't really make your task much harder, there are also anonymous types (or perhaps just a simple struct) you might want to use.


I wonder why there is not such thing like this. However, it is what I prefer to use.

namespace System  {      /// <summary>      /// Helper so we can call some tuple methods recursively without knowing the underlying types.      /// </summary>      internal interface IWTuple      {          string ToString(StringBuilder sb);          int GetHashCode(IEqualityComparer comparer);          int Size { get; }      }        /// <summary>      /// Represents a writable 2-tuple, or pair.      /// </summary>      /// <typeparam name="T1">The type of the tuple's first component.</typeparam>      /// <typeparam name="T2">The type of the tuple's second component.</typeparam>      public class WTuple<T1, T2> : IStructuralEquatable, IStructuralComparable, IComparable, IWTuple      {          private T1 _item1;          private T2 _item2;            #region ImplementedInterfaces          Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer)          {              return comparer.GetHashCode(_item1);          }          Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) {              if (other == null) return false;              WTuple<T1, T2> objTuple = other as WTuple<T1, T2>;//Tuple<t1, t2=""> objTuple = other as Tuple<t1, t2="">;              if (objTuple == null) {                  return false;              }              return comparer.Equals(_item1, objTuple._item1) && comparer.Equals(_item2, objTuple._item2);          }          Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer)          {              if (other == null) return 1;              WTuple<T1, T2> objTuple = other as WTuple<T1, T2>;//Tuple<t1, t2=""> objTuple = other as Tuple<t1, t2="">;              if (objTuple == null)              {                  throw new ArgumentException("ArgumentException_TupleIncorrectType", "other");//ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");              }              int c = 0;              c = comparer.Compare(_item1, objTuple._item1);              if (c != 0) return c;              return comparer.Compare(_item2, objTuple._item2);          }          Int32 IComparable.CompareTo(Object obj)          {              return ((IStructuralComparable)this).CompareTo(obj, Comparer<object>.Default);          }          Int32 IWTuple.GetHashCode(IEqualityComparer comparer)          {              return ((IStructuralEquatable)this).GetHashCode(comparer);          }          string IWTuple.ToString(StringBuilder sb)          {              sb.Append(_item1);              sb.Append(", ");              sb.Append(_item2);              sb.Append(")");              return sb.ToString();          }          int IWTuple.Size          {              get { return 2; }          }          

Next Post »