使用返回的错误消息确定是否存在错误

MPa*_*lak 4 c# return-type

我最近和一个伙伴讨论过返回值只有一个含义.在我之前的工作中,我们使用C++并使用了typedef'ed wBOOL,因此0为wFALSE,1为wTRUE.建筑师说我们也可以返回2,3,4 ......以获取更多信息,我认为这是一个可怕的想法.如果我们期望wTRUE = 1且wFALSE = 0且wBOOL = {wTRUE,wFALSE},则应该避免返回任何其他内容......现在,转到今天的C#.

我最近审查了一段代码,其中有一组函数确定是否存在错误并将字符串返回给用户:

private bool IsTestReady(out string errorMessage)
{
  bool isReady = true;
  errorMessage = string.Empty;
  if(FailureCondition1)
  {
    isReady = false;
    errorMessage = FailureMessage1;
  }
  else if(FailureCondition2)
  {
    isReady = false;
    errorMessage = FailureMessage2;
  }
  //... other conditions
  return isReady;
}
Run Code Online (Sandbox Code Playgroud)

然后,使用这些功能......

private enum Tests
{ TestA, TestB, TestC }
private void UpdateUI()
{
  string error = string.Empty;
  bool isTestReady;
  switch(this.runningTest) // which test are we running (TestA, TestB, or TestC)
  {
    case Tests.TestA:
      isTestReady = IsTestAReady(error);
      break;
    case Tests.TestB:
      isTestReady = IsTestBReady(error);
      break;
    case Tests.TestC:
      isTestReady = IsTestCReady(error);
      break;
  }
  runTestButton.Enabled = isTestReady;
  runTestLabel.Text = error;
}
Run Code Online (Sandbox Code Playgroud)

我想把它们分成两种方法:

private string GetTestAErrorMessage()
{
  //same as IsTestReady, but only returns the error string, no boolean stuffs
}

private bool IsTestAReady
{
  get{ return string.IsNullOrEmpty(GetTestAErrorMessage()); }
}
Run Code Online (Sandbox Code Playgroud)

这是否违反了没有返回值的原则意味着多于一件事?例如,在这种情况下,如果出现错误消息IsNullOrEmpty,则没有错误.我认为这不违反那个原则; 我的合作呢.对我而言,与此无异:

class Person
{
  public int Height {get;}
  public bool IsTall() { return Height > 10; }
}
Run Code Online (Sandbox Code Playgroud)

有关此问题的不同方法的任何想法或建议?我认为out参数是最糟糕的解决方案.

Mat*_*ith 5

返回值和错误消息在技术上不绑定在一起.您可以让开发人员稍后出现并向IsTestReady添加新的故障条件,并且该故障情况可能不会设置错误消息.或者,可能存在消息,但它并不完全代表失败(例如,可能是警告或其他内容),因此可能会设置错误消息参数,但返回值为true.

在这种情况下,异常并不真正起作用,因为StriplingWarrior在他的注释中写的确切原因 - 异常应该用于非正常操作状态,而非就绪测试是正常状态.

一种解决方案可能是删除错误消息参数并让IsTestReady函数返回一个类:

public class TestReadyResult {
    public bool IsReady { get; set; }
    public string Error { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

只有一个要检查的属性 - TestReadyResult.IsReady - 用于测试状态,如果需要,可以将Error属性用于非就绪状态.也没有额外的参数来管理函数调用.