需要为Tuple或keyValuePair等数据结构提供建议,但类型可变

本文关键字:类型 Tuple keyValuePair 数据结构 | 更新日期: 2023-09-27 18:27:58

我需要一个类似TupleKeyValuePair类型的类型,并带有设置其值的选项(可变类型)。对现有的泛型有什么想法可以满足这些需求吗?

(在我看来,字典对我的目的有点过头了)

我也可以编写自己的类,但我希望已经实现了一些可变类型的KeyValuePair

需要为Tuple或keyValuePair等数据结构提供建议,但类型可变

拥有可变元组的问题在于,如果在一个地方更改值,则很容易多次引用同一个元组,而在其他地方也会更改值。因此,如果您确实使用可变元组,则必须非常严格地在适当的地方克隆元组,例如,如果您将其放入集合中。

但是一个可变元组看起来是这样的:

public class MutableTuple<T1, T2> {
    public T1 Item1 { get; set; }
    public T2 Item2 { get; set; }
    public MutableTuple(T1 item1, T2 item2) {
        Item1 = item1;
        Item2 = item2;
    }
}
public class MutableKeyValuePair<TKey, TValue>
{
    public TKey Key { get; set; }
    public TValue Value { get; set; }
}

就是这样。

不,没有。除非您认为object[]是一个:-)

请注意,实现MutableTuple<T1, ...>非常容易。

MutableTuple<T1, T2, T3>的完整实现,几乎等同于Tuple<T1, T2, T3>(各种接口是公开实现的,而不是私有实现的)(部分基于Tuple<>的Mono实现)

public static class MutableTuple
{
    public static MutableTuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
    {
        return new MutableTuple<T1, T2, T3>(item1, item2, item3);
    }
}
[Serializable]
public class MutableTuple<T1, T2, T3> : IComparable, IStructuralEquatable, IStructuralComparable
{
    public T1 Item1 { get; set; }
    public T2 Item2 { get; set; }
    public T3 Item3 { get; set; }
    public MutableTuple(T1 item1, T2 item2, T3 item3)
    {
        this.Item1 = item1;
        this.Item2 = item2;
        this.Item3 = item3;
    }
    public override bool Equals(object obj)
    {
        return this.Equals(obj, EqualityComparer<object>.Default);
    }
    public override int GetHashCode()
    {
        return this.GetHashCode(EqualityComparer<object>.Default);
    }
    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.Append(this.Item1);
        sb.Append(", ");
        sb.Append(this.Item2);
        sb.Append(", ");
        sb.Append(this.Item3);
        sb.Append(")");
        return sb.ToString();
    }
    public int CompareTo(object obj)
    {
        return this.CompareTo(obj, Comparer<object>.Default);
    }
    public bool Equals(object obj, IEqualityComparer comparer)
    {
        if (obj == null)
        {
            return false;
        }
        var tuple = obj as MutableTuple<T1, T2, T3>;
        return tuple != null && (comparer.Equals(this.Item1, tuple.Item1) && comparer.Equals(this.Item2, tuple.Item2)) && comparer.Equals(this.Item3, tuple.Item3);
    }
    public int GetHashCode(IEqualityComparer comparer)
    {
        unchecked
        {
            int hash = 17;
            hash = (hash * 23) + comparer.GetHashCode(this.Item1);
            hash = (hash * 23) + comparer.GetHashCode(this.Item2);
            hash = (hash * 23) + comparer.GetHashCode(this.Item3);
            return hash;
        }
    }
    public int CompareTo(object obj, IComparer comparer)
    {
        if (obj == null)
        {
            return 1;
        }
        var other = obj as MutableTuple<T1, T2, T3>;
        if (other == null)
        {
            throw new ArgumentException();
        }
        int res = comparer.Compare(this.Item1, other.Item1);
        if (res != 0)
        {
            return res;
        }
        res = comparer.Compare(this.Item2, other.Item2);
        if (res != 0)
        {
            return res;
        }
        res = comparer.Compare(this.Item3, other.Item3);
        return res;
    }
}