【问题标题】:Catch and Continue抓住并继续
【发布时间】:2011-08-18 20:45:04
【问题描述】:

我想要一个扩展方法或通用方法,即使有一些异常,我也希望代码继续执行,并继续在列表中记录异常。这是我尝试过的一个例子

    public void ValidateName()
    {
        if (_customer.Name.Length < 5)
            throw new Exception("shortname");
    }
    public void ValidateAge()
    {
        if (_customer.Age < 5)
            throw new Exception("short age");
   }
    internal void Validate()
    {
        this.CatchAndContinue(delegate()
        {
            this.ValidateName(); // throws exception and add to list
            this.ValidateAge(); // but this should also execute
        });
    }
    public void CatchAndContinue(Action action)
    {
        try
        {
            action();
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }
    }

对于当前类,我可以将异常传递给 ValidateName 和 ValidateAge 方法,但我希望我们可以按照我想要的方式进行,而 validate() 方法主体几乎没有变化。我知道从语义上讲这听起来很奇怪,但我需要很多地方来做到这一点。或者如果有更好的方法来实现它

编辑

这个验证是一个简单的例子,并不是在所有场景中它都只是验证器。顺便说一句,在这种情况下,我想向 UI 提供错误列表以及为什么抛出,因为当从 DB 构造模型时(由于 DB 中的数据错误),不应创建此类对象。这些只是关注的例子

【问题讨论】:

    标签: c#


    【解决方案1】:

    不要对控制流使用异常。

    相反,您的验证方法应该返回一个bool,并让验证方法的客户端决定要做什么。除此之外的一步是返回一个 ValidationResult 和一个指示成功或失败的 ValidationStatus 属性和一个记录验证失败原因的 Message 属性。

    【讨论】:

      【解决方案2】:

      收益/回报可能对您有用。

      http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx

      一定要例外吗?

      澄清一下:

      internal IEnumerable<string> Validate()
      {
          if( _customer.Age > 5 ) { yield return "Too Old"; }
          if( _customer.Name.Length < 3 ) { yield return "Not enough name characters"; }
      }
      
      // using it
      IEnumerable<string> errors = myCustomer.Validate();
      if( errors.Length > 0 ) {
          // uh oh, print out the errors!
          foreach( string error in errors ) {
              MsgBox(error);
          }
      }
      

      【讨论】:

      • 看起来很有希望,我会试一试。
      • ie 之前,除了在 c 之后
      • @Hans Passant: ie 之前,除了所有例外(“特征频率”是个人最喜欢的,因为它违反了这两个规则)。
      • @jason - 这是德语,意思是“自己的”。提及 sieg heil 可能不太合适。
      • @Hans i 在 e 之前除了 c 之后?很奇怪。
      【解决方案3】:

      代替throwing Validate 方法中的异常,我将添加到异常列表并返回一个指示成功/失败的bool 值(返回部分是可选的,只有在您关心状态时才添加它验证)。

      类似:

      public void ValidateName()
      {
          if (_customer.Name.Length < 5) {
              LogValidationFailure("shortName");  // you can add more params if needed
              return; // or return false if you need it
          }
      
          // do normal business here
      }
      

      这不仅更干净,而且性能更好,因为 try/catch 和异常抛出很昂贵。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-05
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        • 1970-01-01
        • 2016-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多