C# 设计函数签名-返回值或输出参数

C# 设计函数签名-返回值或输出参数,c#,.net,oop,coding-style,C#,.net,Oop,Coding Style,亲爱的专家们,大家好 我正在设计一个功能,必须处理文件夹中的文件。函数必须说明它处理了多少文件,以及是否有错误。设计此类功能的最佳方法是什么?我在三个选择中进行选择: bool ProcessFiles(out int fileCount) { // return true or false } int ProcessFiles() { // return -1 when failed } int ProcessFiles(out bool success) { // retur

亲爱的专家们,大家好

我正在设计一个功能,必须处理文件夹中的文件。函数必须说明它处理了多少文件,以及是否有错误。设计此类功能的最佳方法是什么?我在三个选择中进行选择:

bool ProcessFiles(out int fileCount)
{
  // return true or false
}

int ProcessFiles()
{
  // return -1 when failed
}

int ProcessFiles(out bool success)
{
  // return count
}
当然,这个例子是对现实生活问题的一个说明。我只想详细说明好的策略。

我会选择

 bool ProcessFiles(out int fileCount)
{
  // return true or false
}

就个人而言,对于单线程方法,我会选择第一种

但是,我告诉您,将此作为后台操作会更好,因此使用
BeginProcessFiles
EndProcessFiles
或事件回调将是确定操作成功与处理了多少文件的更好方法。

我选择:

int ProcessFiles() // returns count
{
   if(error)
   {
       throw new MyException();
   }
}

如果进程失败,为什么不抛出异常?

为什么不:

int ProcessFiles()
{ 

   int num_of_files_processed = 0;

   if(error) 
   { 
       throw new MyException(num_of_files_processed, error_code); 

   return num_of_files_processed;
} 

我也会选择抛出异常的解决方案。有时,例外情况不是一个选项(例如API)。 为什么不创建一个类呢

public class RetrnClass
{
    public int AmountOfFiles { get; set; }
    public int ErrorCode { get; set; }
    public String ErrorMessage { get; set; }
    public Exception ExceptionObject { get; set; }
    public bool IsValid { get { return ExceptionObject == null; } }
    public static implicit operator bool(RetrnClass cls) { return cls.IsValid; }
}

来点更复杂的怎么样

class ProcessingResult
{
    public ProcessingResult(IEnumerable<Foo> processedFiles, IEnumerable<Foo> failures)
    {
        this.ProcessedFiles = processedFiles;
        this.Failures = failures ;
    }

    public IEnumerable<Foo> ProcessedFiles { get; private set; }
    public IEnumerable<Foo> Failures { get; private set; }
}
类处理结果
{
公共进程结果(IEnumerable processedFiles,IEnumerable failures)
{
this.ProcessedFiles=ProcessedFiles;
这个。失败=失败;
}
公共IEnumerable ProcessedFiles{get;private set;}
公共IEnumerable失败{get;private set;}
}
然后你的方法变成:

ProcessingResult ProcessFiles(IEnumerable<Foo> files)
{
    List<Foo> failures = new List<Foo>();
    ProcessingResult result = new ProcessingResult(files, failures);

    foreach (var foo in files)
    {
        // voodoo

        if (error)
            failures.Add(foo);
    }

    return result;
}
ProcessingResult进程文件(IEnumerable文件)
{
列表失败=新建列表();
ProcessInResult结果=新的ProcessInResult(文件、故障);
foreach(文件中的var foo)
{
//伏都教
如果(错误)
失败。添加(foo);
}
返回结果;
}
您可以通过询问
result.failures.any()
来判断是否存在任何失败


ProcessingResult
类可以很容易地进行扩展,以包含更多细节,例如每个失败项目的问题到底是什么,或者每个项目有多个问题,这可能比简单的“this one failed”更有用。

但是我必须提供catch block。更多的编码。@captain:好吧,否则你必须有检查返回值的代码,所以你还必须有一些代码。