考虑一个返回两个值的函数。我们可以这样写:
// Using out:
string MyFunction(string input, out int count)
// Using Tuple class:
Tuple<string, int> MyFunction(string input)
// Using struct:
MyStruct MyFunction(string input)
哪个是最佳做法,为什么?
考虑一个返回两个值的函数。我们可以这样写:
// Using out:
string MyFunction(string input, out int count)
// Using Tuple class:
Tuple<string, int> MyFunction(string input)
// Using struct:
MyStruct MyFunction(string input)
哪个是最佳做法,为什么?
struct
所Eric
提到的去处理。
Answers:
他们每个人都有自己的优点和缺点。
输出参数既快速又便宜,但是需要您传入一个变量,并依赖突变。几乎不可能在LINQ中正确使用out参数。
元组造成垃圾收集压力,并且无法自我记录。“ Item1”不是很描述。
如果自定义结构很大,则复制起来可能会很慢,但如果它们很小,则可以自我记录,并且效率很高。但是,定义一堆用于琐碎用途的自定义结构也很麻烦。
在其他所有条件相同的情况下,我倾向于定制结构解决方案。更好的是制作一个仅返回一个值的函数。为什么首先要返回两个值?
更新:请注意,在撰写本文后六年,C#7中的元组是值类型,因此不太可能产生收集压力。
除了先前的答案,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()
我认为答案取决于函数正在执行的语义以及两个值之间的关系。
例如,这些TryParse
方法采用一个out
参数来接受已解析的值,并返回abool
来指示解析是否成功。这两个值并不真正属于同一类,因此,从语义上讲,这更有意义,并且使用out
参数更易于阅读代码的意图。
但是,如果您的函数返回屏幕上某个对象的X / Y坐标,则这两个值在语义上属于同一类,因此最好使用struct
。
我个人会避免使用atuple
来对外部代码可见的任何东西,因为检索成员的语法很笨拙。
out
参数时,您的答案是更合适的引用类型null
。有一些可为空的不可变类型。
try
适用于协变接口的模式是T TryGetValue(whatever, out bool success)
; 该方法将允许接口IReadableMap<in TKey, out TValue> : IReadableMap<out TValue>
,并让想要将的实例映射Animal
到的实例的代码Car
接受Dictionary<Cat, ToyotaCar>
[using TryGetValue<TKey>(TKey key, out bool success)
。如果TValue
用作ref
参数,则不可能有这种差异。
我将使用使用Out参数的方法,因为在第二种方法中,您将需要创建和对象Tuple类,然后向其添加值,与返回out参数的值相比,我认为这是一项昂贵的操作。尽管如果您想在Tuple类中返回多个值(实际上,仅返回一个out参数就无法实现),那么我将采用第二种方法。
out
。此外,还有一个params
我没有提到的关键字来使问题简单明了。
您没有提到另一个选项,该选项具有自定义类而不是struct。如果数据具有可以通过函数进行操作的语义,或者实例大小足够大(通常大于16个字节),则最好使用自定义类。在公共API中不建议使用“ out”,因为它与指针关联并且需要了解引用类型的工作方式。
https://msdn.microsoft.com/zh-CN/library/ms182131.aspx
元组适合内部使用,但在公共API中使用却很尴尬。因此,对于公共API,我的投票是在struct和class之间。
没有“最佳实践”。这是您感到满意的,并且在您的情况下最有效。只要您对此保持一致,您发布的任何解决方案都不会出现问题。