元组devise要求什么要求?
我正在查看元组的新C#特性。 我很好奇,元组devise要解决什么问题?
你在你的应用中使用了哪些元组?
更新
感谢迄今为止的答案,让我看看我是否有事情在我的脑海里。 已经指出一个元组的一个好例子是坐标。 这看起来正确吗?
var coords = Tuple.Create(geoLat,geoLong);
然后像这样使用元组:
var myLatlng = new google.maps.LatLng("+ coords.Item1 + ", "+ coords.Item2 + ");
那是对的吗?
在编写程序时,想要将一组没有足够通用性的值逻辑地分组在一起以形成课程是非常普遍的。
许多编程语言允许您在逻辑上将一组不相关的值组合在一起,而不用仅以一种方式创buildtypes:
void M(int foo, string bar, double blah)
从逻辑上讲,这与一个方法M完全相同,该方法使用一个三元组int,string,double的参数。 但我希望你不会真的做出:
class MArguments { public int Foo { get; private set; } ... etc
除非MArguments在业务逻辑中有其他含义。
“在一些比类更轻量级的结构中聚集一堆不相关的数据”的概念在很多地方都是有用的,而不仅仅是方法的forms参数列表。 当一个方法有两件事情要返回,或者当你想从两个数据而不是一个数据库中键入一个字典时,这很有用,等等。
像F#这样支持元组types的语言本身就为用户提供了很大的灵活性; 它们是非常有用的一组数据types。 BCL团队决定与F#团队合作,对框架的一种元组types进行标准化,以便每种语言都能从中受益。
但是,在这一点上,C#中的元组没有语言支持。 元组像其他任何框架类一样是另一种数据types; 他们没有什么特别的。 我们正在考虑在假设的未来版本的C#中为元组添加更好的支持。 如果有人对你想要看到的涉及元组的特征有什么想法,我很乐意将它们传递给devise团队。 现实情景比理论思考更有说服力。
元组提供了一个不可变的集合实现
除了元组的常见用法:
- 将共同的价值观组织在一起,而无需创build一个class级
- 从函数/方法返回多个值
- 等等…
不可变对象本质上是线程安全的:
不可变对象在multithreading应用程序中可能非常有用。 multithreading可以处理由不可变对象表示的数据,而不用担心数据被其他线程改变。 因此不可变对象被认为比可变对象更线程安全。
从维基百科的“不可变对象”
它提供了一个替代ref
或out
如果你有一个方法需要返回多个新的对象作为其响应的一部分。
它也允许你使用一个内置types作为返回types,如果你需要做的是混合两个或三个现有types,并且你不想为这个组合添加一个类/结构。 (是否希望一个函数可以返回一个匿名types?这是对这种情况的部分回答。)
有一个“对”types,通常用于快速情况下(如从方法返回两个值)。 元组是F#等函数式语言的核心部分,而C#则是一路走来的。
从函数返回两个值非常有用
就我个人而言,当你处于调查周期或者“玩”时,我发现元组是一个迭代的发展部分。 因为Tuple是通用的,所以在处理generics参数时,我倾向于考虑它 – 特别是当想要开发一个通用的代码段时,我从代码开始,而不是问自己“我怎么会喜欢这个调用看?“
我经常意识到,Tupleforms的集合成为列表的一部分,并且盯着List>并不真正expression列表的意图,或者它如何工作。 我经常“活”与它,但发现自己想要操纵列表,并改变一个值 – 在这一点上,我不一定要创build一个新的元组,因此我需要创build自己的类或结构拿着它,所以我可以添加操纵码。
当然,总是有扩展方法 – 但是通常你不想把这些额外的代码扩展到generics实现。
有时候我想把数据表示成一个元组,而没有可用的元组。 (VS2008)在这种情况下,我刚刚创build了我自己的Tuple类 – 我不使它线程安全(不可变的)。
所以我猜我认为Tuples懒惰的编程是以牺牲描述它的目的的types名称为代价的。 另一个花费是你必须声明元组的签名,而不pipe它是用作参数的。 在开始看起来很臃肿的一些方法之后,你可能会和我一样感觉到值得做一个类,因为它清理了方法签名。
我倾向于首先让class级成为你已经工作过的class级的公共成员。但是,当它超越了简单的价值集合的时候,它就获得了它自己的文件,并且把它从包含的类中移出。
所以现在回想起来,当我不想写课,我想我会用Tuples,只想思考我现在写的东西。 这意味着Tuple的签名可能在半个小时内在文本中发生很大的变化,但是我知道这个方法需要哪些数据,以及它将如何返回将会返回的值。
如果我有机会重构代码,那么我经常会质疑Tuple的位置。
当您不想创build特定types时,Tuple通常用于从函数中返回多个值。 如果你熟悉Python,Python已经有很长一段时间了。
从函数返回多个值。 getCoordinates()不是很有用,如果它只是返回x或y或z,但是让一个完整的类和对象来保存三个整数也似乎很重量级。
一个常见的用法可能是避免创build只包含2个字段的类/结构,而是创build一个Tuple(或现在的KeyValuePair)。 有用的作为返回值,避免传递N出参数…
老问题自2010年以来,现在在2017年Dotnet变化,变得更加聪明。
C#7引入了对元组的语言支持,它使用新的更高效的元组types为元组的字段启用了语义名称。
在vs 2017和.Net 4.7(或者安装nuget包System.ValueTuple)中,你可以用一个非常有效和简单的方式创build/使用一个元组:
var person = (Id:"123", Name:"john"); //create tuble with two items Console.WriteLine($"{person.Id} name:{person.Name}") //access its fields
从方法中返回多个值:
public (double sum, double average) ComputeSumAndAverage(List<double> list) { var sum= list.Sum(); var average = sum/list.Count; return (sum, average); } How to use: var list=new List<double>{1,2,3}; var result = ComputeSumAndAverage(list); Console.WriteLine($"Sum={result.sum} Average={result.average}");
有关更多详细信息,请参阅: https : //docs.microsoft.com/en-us/dotnet/csharp/tuples
我发现在C#中刷新KeyValuePair来迭代Dictionary中的键值对。
我偶然发现了Tuples和Key-Value对之间的性能基准,可能会发现它很有趣。 总而言之,它说Tuple具有优势,因为它是一个calss,所以它被存储在堆中,而不是堆栈中,当作为parameter passing时,它的指针是唯一要做的事情。 但KeyValuePair是一个结构,因此分配速度更快,但使用时速度更慢。
它从函数返回值真的很有帮助。 我们可以有多个值,这在某些情况下是相当节省的。