将来的.NET版本会在C#中支持元组吗?
.Net 3.5不支持元组。太糟糕了,但是不确定将来的.net版本是否支持元组?
解决方案
#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... }
如果我还记得我的计算机科学课,那么元组就是数据。
如果要分组数据,请创建包含属性的类。
如果我们需要类似KeyValuePair的东西,那就可以了。
我会感到惊讶,因为Cis是强类型语言,而元组却适合更动态类型的语言。随着时间的推移,Chas的漂移越来越动态,但这是语法上的糖,而不是底层数据类型的真正转变。
如果在一个实例中需要两个值,则KeyValuePair <>是一个不错的替代品,尽管比较笨拙。我们还可以使结构或者类做相同的事情,并且是可扩展的。
在我看来,匿名类型功能不是元组,而是非常相似的结构。某些LINQ查询的输出是匿名类型的集合,其行为类似于元组。
这是一条语句,它会动态创建一个类型化的元组:-):
var p1 = new {a = "A", b = 3};
参见:http://www.developer.com/net/csharp/article.php/3589916
C很容易通过泛型支持简单的元组(根据先前的回答),并且通过"含糊的键入"(许多可能的语言增强功能之一)来改善类型推断,它们可能非常非常强大。
对于它的价值,Fsupport本身就支持元组,并且已经玩过它,我不确定(匿名)元组会增加多少……简洁性带来的好处,代码清晰度很快就会丢失。
对于单一方法中的代码,有匿名类型。对于超出方法范围的代码,我认为我将坚持使用简单的命名类型。当然,如果将来的Cmake使这些不可变(尽管仍然易于使用)变得更容易,我会很高兴的。
在Cis中实现Tuple类或者重用Fclass的故事只有一半,它们使我们能够相对轻松地创建元组,但实际上并没有语法糖,这使得它们在F#等语言中非常好用。
例如,在F中,我们可以使用模式匹配来提取let语句中元组的两个部分,例如
let (a, b) = someTupleFunc
不幸的是,使用Cwould的Fclasses进行相同的操作却不那么优雅:
Tuple<int,int> x = someTupleFunc(); int a = x.get_Item1(); int b = x.get_Item2();
元组是一种强大的方法,可以从函数调用中返回多个值,而无需使用乱扔类来乱扔代码,也不必诉诸丑陋的ref或者out参数。但是,我认为,如果没有一些语法糖来使它们的创建和访问变得更加优雅,它们的使用就会受到限制。
为了使它们在哈希表或者字典中有用,我们可能希望为GetHashCode和Equals提供重载。
这是我的元组集,它们是由Python脚本自动生成的,所以我可能有些过头了:
链接到Subversion仓库
我们需要一个用户名/密码,他们都是客人
它们基于继承,但是" 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
Lokad共享库(当然是开源)中有一个适当的(不是很快的)CTuple实现,其中包括以下必需功能:
- 2-5个不可变的元组实现
- 正确的DebuggerDisplayAttribute
- 正确的哈希和相等性检查
- 从提供的参数(泛型由编译器推断)生成元组的助手,以及用于基于集合的操作的扩展。
- 经过生产测试。
我刚刚从MSDN杂志上阅读了这篇文章:Building Tuple
以下是摘录:
The upcoming 4.0 release of Microsoft .NET Framework introduces a new type called System.Tuple. System.Tuple is a fixed-size collection of heterogeneously typed data. ? ?
?
Like an array, a tuple has a fixed size that can't be changed once it has been created. Unlike an array, each element in a tuple may be a different type, and a tuple is able to guarantee strong typing for each element.
?
There is already one example of a tuple floating around the Microsoft .NET Framework, in the System.Collections.Generic namespace: KeyValuePair. While KeyValuePair can be thought of as the same as Tuple, since they are both types that hold two things, KeyValuePair feels different from Tuple because it evokes a relationship between the two values it stores (and with good reason, as it supports the Dictionary class). Furthermore, tuples can be arbitrarily sized, whereas KeyValuePair holds only two things: a key and a value.
虽然某些语言(例如Fhave具有针对元组的特殊语法),但是我们可以从任何语言中使用新的通用元组类型。回顾第一个示例,我们可以看到,虽然元组很有用,但在没有元组语法的语言中,元组可能过于冗长:
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); } }
使用C3.0中的var关键字,我们可以删除元组变量上的类型签名,从而使代码更具可读性。
var t = new Tuple<string, int>("Hello", 4);
我们还向静态Tuple类添加了一些工厂方法,这使使用支持类型推断的语言(如C#)构建元组变得更加容易。
var t = Tuple.Create("Hello", 4);
我的开源.NET Sasa库已有元组很多年了(还有很多其他功能,例如完整的MIME解析)。我已经在生产代码中使用了好几年了。