Je me demande pourquoi il n'y a pas une telle chose. Cependant, c'est ce que je préfère utiliser.
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<T1,T2> 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<T1,T2> 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<T1,T2> 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<T1,T2> 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<T1,T2> 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<T1,T2> instance.
/// </summary>
/// <returns>The string representation of this System.WTuple<T1,T2> object.</returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("(");
return ((IWTuple)this).ToString(sb);
}
#endregion
}
}
Je pense que dans la programmation OO, Tuple est habituellement juste une paresse de développeur pour décrire ses structures de données. Dans la programmation fonctionnelle, cependant, c'est le veau d'or. Je ne dis pas que ce soit bon ou mauvais et je suis aussi paresseux parfois. Juste qu'il peut y avoir des meilleures pratiques différentes à différents cas d'utilisation. – Rbjz