代码之家  ›  专栏  ›  技术社区  ›  Drake

Why Tuple's items are ReadOnly?

  •  45
  • Drake  · 技术社区  · 14 年前

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

    But I discover that 元组 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?

    3 回复  |  直到 7 年前
        1
  •  47
  •   Noldorin    11 年前

    元组起源于 functional programming . In (purely) functional programming, 一切 通过设计是不变的-某个变量在任何时候都只有一个定义,就像数学中那样。在将功能样式集成到C/.NET中时,.NET设计人员明智地遵循了相同的原则,尽管它最终是一个主要的需求(混合?)语言。

    注意:尽管我怀疑元组是不可变的这一事实并没有真正让您的任务更加困难,但您可能还需要使用匿名类型(或者可能只是一个简单的结构)。

        2
  •  2
  •   xamid Cascabel    10 年前

    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
        }
    }
    
        3
  •  -3
  •   Greg    10 年前

    您只得到了itemx属性的getter,没错,但是我找到了一种方法,首先用空值声明一个元组,然后在后面填充它们。

    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);
    

    The tplTemp passed as an out parameter will have it's 2 items values from the collection. So that's a way of doing in case this can help's someone.