返回代码或输出参数?

时间:2010-09-10 12:32:12

标签: c# pass-by-reference

我正在制作一个从服务器获取文件名列表的方法,但我遇到了一个我无法回答的问题。

该方法返回两件事:

  • SftpResult这是一个包含各种返回代码的枚举。
  • 文件名列表。

在这三个签名中:

public static ArrayList GetFileList(string directory, out SftpResult result)

public static SftpResult GetFileList(string directory, out ArrayList fileNames)

public static SftpFileListResult GetFileList(string directory)

(其中SftpFileListResultSftpResultArrayList的合成对象)

这是首选的,为什么?

7 个答案:

答案 0 :(得分:32)

我个人更喜欢最后一个选项(尽管使用List<T>ReadOnlyCollection<T>代替ArrayList)。 out参数基本上是一种返回多个值的方法,而通常更好地封装了这些值。

.NET 4中的另一个选项是

Tuple<SftpResult, ArrayList> GetFileList(string directory)

明确地说,“这个方法返回两件事......我已经为这个特殊情况将它们打包在一起了,但是不值得进一步封装它们:它们不值得在一个单独的类型中编写”。< / p>

(如果您不使用.NET 4,则可以随时编写自己的Tuple类型。)

答案 1 :(得分:9)

我更愿意将它包装在一个返回对象中:

class FileResult
{
    public FileResult(SftpResult resultCode, IEnumerable<string> files)
    {
         ResultCode = resultCode;
         FileList = new List<string>(files);
    }
    public SftpResult ResultCode { get; private set; }
    public IEnumerable<string> FileList { get; private set; }
}

不使用out感觉更清洁。

答案 2 :(得分:4)

我更喜欢最后的选择。 Out参数很少使用,对某些人来说可能会让人感到惊讶/困惑。创建复合结果对象是一个干净的解决方案。唯一的缺点是您必须仅为此目的创建一个类。

答案 3 :(得分:3)

我会说第三个,因为它在一个位置封装了你需要的逻辑。我只能假设SftpResult和ArrayList返回方法应该是私有的,然后组成复合返回对象的内部逻辑。

答案 4 :(得分:2)

我会成功:

public static bool GetFileList(string directory, out SftpResult result, out ArrayList fileNames)

因此,如果GetFileList失败,那么函数的作用就不会产生混淆,而且我会返回一个bool。

答案 5 :(得分:2)

如果你喜欢设计,其中一个函数做两件事,那么我会使用一个元组一个Jon或一个返回对象一个Fredrik。

如果你想成为OOPy,你可以让类型系统完成工作:

abstract class FtpResult { ... }
sealed class FileList : FtpResult { ... }
sealed class Error : FtpResult { ... }
...
sealed class FtpService
{
    ...
    public FtpResult GetFileList(string directory) { ... }
    ...
}
...
var result = service.GetFileList(dir);
var error = result as Error;
var list = result as FileList;
if (error != null) { ... }
else if (list != null)
{
    foreach(var name in list.Files) { ... }
}
... 

答案 6 :(得分:1)

为什么不提供全部三个?我不喜欢在我的函数调用中输出参数,但我很欣赏它在很多时候都需要它们。如果您不知道支持哪个签名,那么支持所有三个。最终,选择是在来电者的一​​边,你可以做的最好的事情是提供这种选择。