Why are Tuple ReadOnly items?

I thought to use the Tuple class to store 2 integer data (StartAddress, EndAddress) that I need in my program.

But I found that the Tuple elements are ReadOnly, so if I need to set the value for the element, I need to re-create the Tuple instance.

What is the reason for this design decision?

+41
tuples readonly
Jun 28 2018-10-06T00:
source share
3 answers

Tuples arose in functional programming . In (purely) functional programming, everything is unchanged in design β€” a particular variable has only one definition at all times, as in mathematics. .NET designers wisely followed the same principle when they integrated the functional style into C # /. NET, despite the fact that it was ultimately the main imperative (hybrid?) Language.

Note. Although I suspect that the fact that tuples are immutable does not make your task much more difficult, there are also anonymous types (or perhaps just a simple structure) that you might want to use.

+40
Jun 28 '10 at 9:52
source share

I wonder why this is not happening. However, this 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 first component.</typeparam> /// <typeparam name="T2">The type of the tuple 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 first component.</param> /// <param name="item2">The value of the tuple 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 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 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 } } 
+1
Mar 18 '14 at 8:57
source share

You only have ItemX property getters, this is correct, but I found a way to create confusion with empty values ​​first and fill them with afterwords.

If you do something like this:

 Dictionary <string, Tuple<string, string>> mydic = new Dictionary<string,Tuple<string,string>>(); Tuple<string, string> tplTemp = new Tuple<string, string>("", ""); mydic.TryGetValue("akey", out tplTemp); 

In tplTemp, passed as an out parameter, values ​​from 2 elements from the collection will be indicated. So there’s a way to do this in case it can help someone.

-one
Feb 13 '14 at 10:15
source share



All Articles