什么是C++ std :: pair的C#模拟?

Ale*_*yev 277 .net c# base-class-library data-structures std-pair

我很感兴趣:C#std::pair在C++中的模拟是什么?我找到了System.Web.UI.Pair课程,但我更喜欢基于模板的课程.

谢谢!

Jor*_*ira 313

从.NET4.0开始提供元组并支持泛型:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
Run Code Online (Sandbox Code Playgroud)

在以前的版本中,您可以使用System.Collections.Generic.KeyValuePair<K, V>或解决方案如下:

public class Pair<T, U> {
    public Pair() {
    }

    public Pair(T first, U second) {
        this.First = first;
        this.Second = second;
    }

    public T First { get; set; }
    public U Second { get; set; }
};
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

Pair<String, int> pair = new Pair<String, int>("test", 2);
Console.WriteLine(pair.First);
Console.WriteLine(pair.Second);
Run Code Online (Sandbox Code Playgroud)

这输出:

test
2
Run Code Online (Sandbox Code Playgroud)

甚至这个链式对:

Pair<Pair<String, int>, bool> pair = new Pair<Pair<String, int>, bool>();
pair.First = new Pair<String, int>();
pair.First.First = "test";
pair.First.Second = 12;
pair.Second = true;

Console.WriteLine(pair.First.First);
Console.WriteLine(pair.First.Second);
Console.WriteLine(pair.Second);
Run Code Online (Sandbox Code Playgroud)

那输出:

test
12
true
Run Code Online (Sandbox Code Playgroud)

  • 由于无法在对象创建表达式(构造函数调用)中推断出属于泛型类的类型参数,因此BCL的作者创建了一个名为`Tuple`的非泛型辅助类.因此你可以说`Tuple.Create("Hello",4)`这比`new Tuple <string,int>("Hello",4)`容易一些.(顺便说一句,.NET4.0自2010年以来就已经在这里.) (6认同)
  • 请注意,`Tuple <>`实现了具有值语义的固定`Equals`和`GetHashCode`,这很棒.在实现自己的元组时请记住. (4认同)

Jay*_*ker 88

System.Web.UI包含Pair该类,因为它在ASP.NET 1.1中被大量使用作为内部ViewState结构.

2017年8月更新: C#7.0/.NET Framework 4.7提供了使用System.ValueTuplestruct 声明具有命名项的元组的语法.

//explicit Item typing
(string Message, int SomeNumber) t = ("Hello", 4);
//or using implicit typing 
var t = (Message:"Hello", SomeNumber:4);

Console.WriteLine("{0} {1}", t.Message, t.SomeNumber);
Run Code Online (Sandbox Code Playgroud)

有关更多语法示例,请参阅MSDN.

2012年6月更新: Tuples自4.0版以来一直是.NET的一部分.

这是一篇早期文章,描述了.NET4.0中的包含和对泛型的支持:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,元组是只读的.也就是说,你不能这样做:`tuple.Item1 = 4;` (2认同)
  • 元组正是我想要的.谢谢. (2认同)

Kon*_*lph 38

不幸的是,没有.你可以System.Collections.Generic.KeyValuePair<K, V>在很多情况下使用它.

或者,您可以使用匿名类型来处理元组,至少在本地:

var x = new { First = "x", Second = 42 };
Run Code Online (Sandbox Code Playgroud)

最后一种方法是创建一个自己的类.

  • 为了清楚起见,匿名类型也是只读的 - [msdn](http://msdn.microsoft.com/en-us/library/bb397696.aspx). (2认同)

Ken*_* K. 20

C#具有4.0版本的元组.


小智 11

一些答案似乎错了,

  1. 你不能使用字典如何存储对(a,b)和(a,c).不应将对概念与关键和值的关联查找混淆
  2. 很多上面的代码似乎都很可疑

这是我的配对课程

public class Pair<X, Y>
{
    private X _x;
    private Y _y;

    public Pair(X first, Y second)
    {
        _x = first;
        _y = second;
    }

    public X first { get { return _x; } }

    public Y second { get { return _y; } }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        if (obj == this)
            return true;
        Pair<X, Y> other = obj as Pair<X, Y>;
        if (other == null)
            return false;

        return
            (((first == null) && (other.first == null))
                || ((first != null) && first.Equals(other.first)))
              &&
            (((second == null) && (other.second == null))
                || ((second != null) && second.Equals(other.second)));
    }

    public override int GetHashCode()
    {
        int hashcode = 0;
        if (first != null)
            hashcode += first.GetHashCode();
        if (second != null)
            hashcode += second.GetHashCode();

        return hashcode;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一些测试代码:

[TestClass]
public class PairTest
{
    [TestMethod]
    public void pairTest()
    {
        string s = "abc";
        Pair<int, string> foo = new Pair<int, string>(10, s);
        Pair<int, string> bar = new Pair<int, string>(10, s);
        Pair<int, string> qux = new Pair<int, string>(20, s);
        Pair<int, int> aaa = new Pair<int, int>(10, 20);

        Assert.IsTrue(10 == foo.first);
        Assert.AreEqual(s, foo.second);
        Assert.AreEqual(foo, bar);
        Assert.IsTrue(foo.GetHashCode() == bar.GetHashCode());
        Assert.IsFalse(foo.Equals(qux));
        Assert.IsFalse(foo.Equals(null));
        Assert.IsFalse(foo.Equals(aaa));

        Pair<string, string> s1 = new Pair<string, string>("a", "b");
        Pair<string, string> s2 = new Pair<string, string>(null, "b");
        Pair<string, string> s3 = new Pair<string, string>("a", null);
        Pair<string, string> s4 = new Pair<string, string>(null, null);
        Assert.IsFalse(s1.Equals(s2));
        Assert.IsFalse(s1.Equals(s3));
        Assert.IsFalse(s1.Equals(s4));
        Assert.IsFalse(s2.Equals(s1));
        Assert.IsFalse(s3.Equals(s1));
        Assert.IsFalse(s2.Equals(s3));
        Assert.IsFalse(s4.Equals(s1));
        Assert.IsFalse(s1.Equals(s4));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你没有实现IEquatable,你将获得拳击.要正确完成课程还有很多工作要做. (3认同)

Paw*_*cki 9

除了自定义类或 .Net 4.0 元组之外,从 C# 7.0 开始,还有一个名为 ValueTuple 的新功能,它是一个可以在这种情况下使用的结构。而不是写:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
Run Code Online (Sandbox Code Playgroud)

并通过t.Item1和访问值t.Item2,您可以简单地这样做:

(string message, int count) = ("Hello", 4);
Run Code Online (Sandbox Code Playgroud)

甚至:

(var message, var count) = ("Hello", 4);
Run Code Online (Sandbox Code Playgroud)


Ore*_*ost 8

如果它是关于词典之类的,那么你正在寻找System.Collections.Generic.KeyValuePair <TKey,TValue>.