任何原因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语法糖。 TupleValueTuple之间的区别是:

  • ValueTuple是一个值类型,因此不需要在堆上分配对象
  • ValueTuple是可变的
  • ValueTuple (显然)具有内置语言支持,它允许您通过自定义属性( TupleElementNamesAttribute )命名元组项。 使用Tuple ,你只能获得Item1Item2等。

每个新语言版本的某些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 } 

并且在大多数情况下,从方法返回多个值是代码气味。 你应该总是将你返回的课程包装成比FirstSecond更好地描述你的价值观。