Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 824
Drake Avatar asked Jun 28 '10 09:06

Drake


People also ask

Why are tuples immutable in C#?

One thing that makes tuples distinct is that they are immutable. That means you can't change them at all once they have been created. Any properties in that tuple are going to be read-only. It also means that the size of the tuple is fixed after you create it.

Why anonymous types are preferred over tuples?

Tradeoffs. You might want to always use ValueTuple over Tuple, and anonymous types, but there are tradeoffs you should consider. The ValueTuple types are mutable, whereas Tuple are read-only. Anonymous types can be used in expression trees, while tuples cannot.

What is System ValueTuple?

ValueTuple is a structure introduced in C# 7.0 which represents the value type Tuple. It is already included in . NET Framework 4.7 or higher version. It allows you to store a data set which contains multiple values that may or may not be related to each other.


2 Answers

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.

like image 53
Noldorin Avatar answered Oct 22 '22 03:10

Noldorin


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; }         }         #endregion          #region WTuple         /// <summary>         /// Initializes a new instance of the System.WTuple&lt;T1,T2&gt; class.         /// </summary>         /// <param name="item1">The value of the tuple's first component.</param>         /// <param name="item2">The value of the tuple's second component.</param>         public WTuple(T1 item1, T2 item2)         {             _item1 = item1;             _item2 = item2;         }         /// <summary>         /// Gets or sets the value of the current System.WTuple&lt;T1,T2&gt; object's first component.         /// </summary>         public T1 Item1         {             get { return _item1; }             set { _item1 = value; }         }         /// <summary>         /// Gets or sets the value of the current System.WTuple&lt;T1,T2&gt; object's second component.         /// </summary>         public T2 Item2         {             get { return _item2; }             set { _item2 = value; }         }         /// <summary>         /// Returns a value that indicates whether the current System.WTuple&lt;T1,T2&gt; object         /// is equal to a specified object.         /// </summary>         /// <param name="obj">The object to compare with this instance.</param>         /// <returns>true if the current instance is equal to the specified object; otherwise,         /// false.</returns>         public override Boolean Equals(Object obj)         {             return ((IStructuralEquatable)this).Equals(obj, EqualityComparer<object>.Default);         }         /// <summary>         /// Returns the hash code for the current System.WTuple&lt;T1,T2&gt; object.         /// </summary>         /// <returns>A 32-bit signed integer hash code.</returns>         public override int GetHashCode()         {             return ((IStructuralEquatable)this).GetHashCode(EqualityComparer<object>.Default);         }         /// <summary>         /// Returns a string that represents the value of this System.WTuple&lt;T1,T2&gt; instance.         /// </summary>         /// <returns>The string representation of this System.WTuple&lt;T1,T2&gt; object.</returns>         public override string ToString()         {             StringBuilder sb = new StringBuilder();             sb.Append("(");             return ((IWTuple)this).ToString(sb);         }         #endregion     } } 
like image 43
xamid Avatar answered Oct 22 '22 01:10

xamid