任何原因tu使用C#7元组返回值的参数?
我刚看了一段video,展示了C#7的新function 。 其中,它引入了返回元组类型的可能性(例如: (int, int)
,我相信,它只是Tuple
的语法糖)。 因此,如果我们有一个返回多个值的方法,C#中有3种可能的方法:
(int first, int second) ReturnTuple() { return (1, 2); } int ReturnOutParam(out int second) { second = 2; return 1; } CustomObject ReturnObject() { return new CustomObject { First = 1, Second = 2 }; }
我相信,没有更多的方法可以做到 – 如果是的话,请纠正我。
这三种方法中的哪一种是正确的? 在哪些情况下我们可以使用其余的两个? 对于每一个新的C#版本,我都觉得有一两种设计模式在.NET世界中已经过时了。 一些function非常有用(如generics,部分,LINQ,lambdas,async / await或null传播器)。 其他人非常情绪化(动态,名称)。 然后还有那些对我没有意义的东西(属性自动初始化器,元组返回值或本地函数)。
首先,像(int, int)
这样的元组是ValueTuple
语法糖。 Tuple
和ValueTuple
之间的区别是:
-
ValueTuple
是一个值类型,因此不需要在堆上分配对象 -
ValueTuple
是可变的 -
ValueTuple
(显然)具有内置语言支持,它允许您通过自定义属性(TupleElementNamesAttribute
)命名元组项。 使用Tuple
,你只能获得Item1
,Item2
等。
每个新语言版本的某些function都会过时。 例如, delegate { }
语法被lambdas取代。 你可以争辩说out
参数适合这个类别,但这是主观的。 然而,所有function都需要保持在那里以实现向后兼容。
例如, bool int.TryParse(string input, out int value)
应该变成int? int.TryParse(string input)
int? int.TryParse(string input)
,包含语言的可空值类型,但旧函数已经存在于框架中,因此它必须保留。
我的经验法则是:将值元组用于私有方法或实用程序函数,但是对于任何公共API更喜欢完整的结构,它只是感觉更干净。 除了偶尔使用私人方法外,我通常会避免使用params。
我不明白为什么这些新function对你没有意义:
- 属性自动初始化器终于存在,它们应该首先与自动属性一起实现,但由于时间限制可能会被跳过。 这是代码可读性的明显胜利,它增加了一个始终存在于字段中的function。
- 元组返回值是你问题的主题,它也是对旧元组的明显可读性胜利。 能够命名你的元组项目说明了一切。
- 本地函数将主要用于实现迭代器模式,但我偶尔希望有这样的function并使用lambda来解决它。
对我来说,它仍然取决于具体情况。 例如,对于TryParse
它的可读性更高:
if (int.TryParse("123", out var i)) { // i }
比
var (success, i) = int.TryParse("123"); if (success) { // i }
并且在大多数情况下,从方法返回多个值是代码气味。 你应该总是将你返回的课程包装成比First
和Second
更好地描述你的价值观。