考虑一个返回两个值的函数。我们可以写:
// Using out:
string MyFunction(string input, out int count)
// Using Tuple class:
Tuple<string, int> MyFunction(string input)
// Using struct:
MyStruct MyFunction(string input)
哪一个是最佳做法?为什么?
答案 0 :(得分:81)
他们各有利弊。
Out参数快速且便宜,但要求您传入变量,并依赖于变异。几乎不可能在LINQ中正确使用out参数。
元组会产生收集压力,并且是非自我记录的。 “Item1”不是很具描述性。
如果自定义结构很大,则复制速度很慢,但是它们是自我文档的,如果它们很小则效率很高。然而,为琐碎的用途定义一大堆自定义结构也是一件痛苦的事。
我倾向于自定义结构解决方案所有其他条件相同。更好的方法是创建一个只返回一个值的函数。你为什么要首先返回两个值?
更新:请注意,编写本文六年后发布的C#7中的元组是值类型,因此不太可能产生收集压力。
答案 1 :(得分:19)
我认为答案取决于函数正在做什么的语义,以及这两个值之间的关系。
例如,TryParse
方法使用out
参数接受已解析的值,并返回bool
以指示解析是否成功。这两个值并不真正属于一体,因此,从语义上讲,它更有意义,并且代码的意图更容易阅读,使用out
参数。
但是,如果您的函数返回屏幕上某个对象的X / Y坐标,那么这两个值在语义上属于一起,最好使用struct
。
我个人避免使用tuple
来查看外部代码可见的任何内容,因为检索成员的方法很笨拙。
答案 2 :(得分:15)
除了之前的答案之外,C#7还带来了值类型元组,与System.Tuple
不同,它是一种引用类型,并且还提供了改进的语义。
您仍然可以将其保留为未命名,并使用.Item*
语法:
(string, string, int) getPerson()
{
return ("John", "Doe", 42);
}
var person = getPerson();
person.Item1; //John
person.Item2; //Doe
person.Item3; //42
但是这个新功能真正强大的是具有命名元组的能力。所以我们可以像这样重写上面的内容:
(string FirstName, string LastName, int Age) getPerson()
{
return ("John", "Doe", 42);
}
var person = getPerson();
person.FirstName; //John
person.LastName; //Doe
person.Age; //42
也支持解构:
(string firstName, string lastName, int age) = getPerson()
答案 3 :(得分:1)
我将使用Out参数的方法,因为在第二种方法中你需要创建和对象的Tuple类,然后为它添加值,我认为与返回out参数中的值相比,这是一个代价高昂的操作。虽然如果你想在Tuple Class中返回多个值(实际上只能通过返回一个参数来完成),那么我将采用第二种方法。
答案 4 :(得分:1)
You did not mention one more option, which is having a custom class instead of struct. If the data has semantics associated to it which can be operated upon by functions, or the instance size is big enough (> 16 bytes as a rule of thumb), a custom class may be preferred. Use of "out" is not recommended in public API because of its association to pointers and requiring understanding of how reference types work.
https://msdn.microsoft.com/en-us/library/ms182131.aspx
Tuple is good for internal use, but it usage is awkward in public API. So, my vote is between struct and class for public API.
答案 5 :(得分:0)
没有“最佳做法”。这是你感到舒服的,在你的情况下最有效的。只要您与此保持一致,您发布的任何解决方案都没有问题。