开发者

Designing function signature - return value or out parameter

开发者 https://www.devze.com 2023-01-30 10:30 出处:网络
Hi my dear fellow experts, I am designing one function that must pro开发者_StackOverflow社区cess files in the folder. The function must say how much files it has processed and also if there is error.

Hi my dear fellow experts,

I am designing one function that must pro开发者_StackOverflow社区cess files in the folder. The function must say how much files it has processed and also if there is error. What is best way to design such function? I am choosing between three choices:

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

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

int ProcessFiles(out bool success)
{
  // return count
}

Of course this example is rather an illustration to real life problems. I just want to elaborate good strategy.


I'd go for:

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


i would go for

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


Why not throw an exception if the process fails?


Personally, for a single-threaded approach, I'd choose the first one.

However, I put it to you that making this a background operation would be preferable and therefore having a BeginProcessFiles and either EndProcessFiles or an event callback would be a better way of determining the success of the operation and how many files were processed.


Why not:

int ProcessFiles()
{ 

   int num_of_files_processed = 0;

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

   return num_of_files_processed;
} 


I'd also choise the solution throwing an exception. Sometimes an exception is not an option (e.g. API). Why not creating a class?

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; }
}


How about something more sophisticated?

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; }
}

Then you method becomes:

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;
}

You can tell if there were any failures by asking result.Failures.Any().

The ProcessingResult class can easily be extended to contain more detail, such as exactly what the problem was with each failed item, or multiple problems per item, which may be more use than a simple "this one failed".

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号