.Net 3.5不支持元组。太糟糕了,但是不确定将来的.net版本是否支持元组?
Answers:
我刚刚从MSDN杂志上阅读了这篇文章:Building Tuple
以下是摘录:
即将发布的Microsoft .NET Framework 4.0版本引入了一种称为System.Tuple的新类型。System.Tuple是固定大小的异构类型数据的集合。
像数组一样,元组具有固定的大小,一旦创建就无法更改。与数组不同,元组中的每个元素可以是不同的类型,并且元组能够保证每个元素的强类型化。
在System.Collections.Generic命名空间中,已经有一个在Microsoft .NET Framework周围浮动元组的示例:KeyValuePair。虽然可以将KeyValuePair视为与Tuple相同,但由于它们都是两种类型,所以KeyValuePair与Tuple有所不同,因为它唤起了存储的两个值之间的关系(并且有充分的理由,因为它支持Dictionary类)。
此外,元组的大小可以任意设置,而KeyValuePair仅包含两件事:一个键和一个值。
虽然某些语言(例如F#)具有针对元组的特殊语法,但是您可以从任何语言中使用新的通用元组类型。回顾第一个示例,我们可以看到,虽然有用,但是在没有元组语法的语言中,元组可能过于冗长:
class Program {
static void Main(string[] args) {
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
PrintStringAndInt(t.Item1, t.Item2);
}
static void PrintStringAndInt(string s, int i) {
Console.WriteLine("{0} {1}", s, i);
}
}
使用C#3.0中的var关键字,我们可以删除元组变量上的类型签名,从而使代码更具可读性。
var t = new Tuple<string, int>("Hello", 4);
我们还向静态Tuple类添加了一些工厂方法,这使使用支持类型推断的语言(如C#)构建元组变得更加容易。
var t = Tuple.Create("Hello", 4);
#region tuples
public class Tuple<T>
{
public Tuple(T first)
{
First = first;
}
public T First { get; set; }
}
public class Tuple<T, T2> : Tuple<T>
{
public Tuple(T first, T2 second)
: base(first)
{
Second = second;
}
public T2 Second { get; set; }
}
public class Tuple<T, T2, T3> : Tuple<T, T2>
{
public Tuple(T first, T2 second, T3 third)
: base(first, second)
{
Third = third;
}
public T3 Third { get; set; }
}
public class Tuple<T, T2, T3, T4> : Tuple<T, T2, T3>
{
public Tuple(T first, T2 second, T3 third, T4 fourth)
: base(first, second, third)
{
Fourth = fourth;
}
public T4 Fourth { get; set; }
}
#endregion
并使声明更漂亮:
public static class Tuple
{
//Allows Tuple.New(1, "2") instead of new Tuple<int, string>(1, "2")
public static Tuple<T1, T2> New<T1, T2>(T1 t1, T2 t2)
{
return new Tuple<T1, T2>(t1, t2);
}
//etc...
}
Tuple<T1,T2,T3>
作为传递Tuple<T1,T2>
?答案可能不是。
Lokad共享库(当然是开源)中有一个适当的(不是很快的)C#Tuple实现,其中包括以下必需功能:
在C#中实现Tuple类或在F#中重用F#类只是故事的一半-这些使您能够相对轻松地创建元组,但实际上不是语法糖,这使得它们在F#等语言中使用起来非常好。
例如,在F#中,您可以使用模式匹配来提取let语句中元组的两个部分,例如
let (a, b) = someTupleFunc
不幸的是,使用来自C#的F#类执行相同的操作会不太优雅:
Tuple<int,int> x = someTupleFunc();
int a = x.get_Item1();
int b = x.get_Item2();
元组表示一种强大的方法,可以从函数调用中返回多个值,而无需使用乱扔类来乱扔代码,也不必诉诸丑陋的ref或out参数。但是,我认为,如果没有一些语法糖来使它们的创建和访问变得更加优雅,它们的使用就会受到限制。
我认为,匿名类型功能不是元组,而是非常相似的结构。某些LINQ查询的输出是匿名类型的集合,其行为类似于元组。
这是一条语句,它会动态创建一个类型化的元组:-):
var p1 = new {a = "A", b = 3};
参见:http : //www.developer.com/net/csharp/article.php/3589916
C#7本机支持元组:
var unnamedTuple = ("Peter", 29);
var namedTuple = (Name: "Peter", Age: 29);
(string Name, double Age) typedTuple = ("Peter", 29);
ValueTuple
结构。但是,您可以例如通过诸如ValueTupleBridge之类的NuGet包来提供这些。
C#非常容易地通过泛型支持简单元组(根据先前的回答),并且通过“含糊的输入”(许多C#语言增强功能之一)来改进类型推断,它们可能非常非常强大。
对于什么是值得,F#支持原生的元组,并且已经打了它,我不知道这(匿名)元组增加多少...你在简洁收获了什么你失去非常的代码清晰快速。
对于单一方法中的代码,有匿名类型;对于超出方法范围的代码,我认为我将坚持使用简单的命名类型。当然,如果将来使用C#可以更轻松地使这些不可变(尽管仍然易于使用),我会很高兴的。
{ j = ErrorCode, h = ResultObj } = SomeFunction()
(where j
and h
are locals)之类的东西比tuple有用得多。
这是我的一组元组,它们是由Python脚本自动生成的,所以我可能有些过头了:
您需要一个用户名/密码,他们都是访客
它们基于继承,但是即使碰巧两个前成员的值相同,Tuple<Int32,String>
也不会等于Tuple<Int32,String,Boolean>
。
他们还实现了GetHashCode和ToString等,以及许多小的辅助方法。
用法示例:
Tuple<Int32, String> t1 = new Tuple<Int32, String>(10, "a");
Tuple<Int32, String, Boolean> t2 = new Tuple<Int32, String, Boolean>(10, "a", true);
if (t1.Equals(t2))
Console.Out.WriteLine(t1 + " == " + t2);
else
Console.Out.WriteLine(t1 + " != " + t2);
将输出:
10, a != 10, a, True
Tuple<Int32, String> t1 = new Tuple<Int32, String, Boolean>(10, "a", true);
等。我不确定是否需要这种情况。
如果我还记得我的计算机科学课,那么元组就是数据。
如果要对数据分组,请创建包含属性的类。如果您需要类似KeyValuePair的东西,那就可以了。
为了使它们在哈希表或字典中有用,您可能希望为GetHashCode和Equals提供重载。