【问题标题】:Throw exception without any real errors?抛出异常而没有任何真正的错误?
【发布时间】:2021-11-10 20:11:16
【问题描述】:

我可以对我设置的条件使用 try-catch-throw,而不是实际错误吗?例如,

int x = 0;
if (x > 0)
{ throw new Exception("X can't be more than 0!");}

所以 x 大于 0 并没有技术上的错误,但这是我所拥有的条件。另外,我知道 throw 会终止程序,但之后我需要程序继续运行。

编辑:这是我正在尝试实现的代码的一部分:

public bool CheckIfEligible()
{

    
        if (DateTime.Compare(DateTime.Now, this.startTime) > 0)
        {
            Console.WriteLine("\n" + "ERROR: choose a later date");

            return false;


        }
    // bunch of other conditions here...
    else
        return true;

}

【问题讨论】:

  • 当然可以。调用代码可以像捕获任何其他异常一样捕获它。这是 ArgumentOutOfRangeException 等异常的标准用例。
  • 换成 try...catch
  • 是的;去尝试一下!在 Q/A 堆栈的 cmets 中讨论这个是没有意义的 :)
  • 首先,是的,你绝对可以。虽然 CPU 不会在 x 大于 0 时融化,但您有一个合同中断,因为您不期望也不允许 x 大于 0。在这种情况下,这是绝对正确的抛出异常。但是,对于这种特殊类型的违约行为,我建议您使用ArgumentOutOfRangeException
  • 为了挽救这个问题,发布一个您实际运行的代码的最小完整示例。

标签: c# exception


【解决方案1】:

实际上,创建代表您的域的例外情况的自定义例外通常是一种很好的做法。

public class StartCannotBeInThePastException : Exception
{
    public StartCannotBeInThePastException(string message) : base(message)
    { }
}

这样可以专门处理那些表示特定域相关错误的异常,然后记录详细信息或返回给客户端,而不是例如使应用程序崩溃。进行自定义异常的另一个好处是您可以在代码中明确说明您的业务规则,使其更易于阅读。

在这个例子中会是这样的:

public void CheckIfEligible()
{
    if (DateTime.Now > this.startTime)
    {
        throw new StartCannotBeInThePastException();
    }
}

异常有一些隐藏的性能成本,如果你有兴趣,我给你留下这个解释很好的视频。

https://youtu.be/2f2elFRmeLE

【讨论】:

    【解决方案2】:

    这假设您没有在某处将此代码作为库提供,而是主要关心在开发时进行这些类型的检查。

    C# 具有 [ConditionalAttribute("DEBUG")] 属性,仅当代码处于 DEBUG 模式且未释放时,可以将其添加到执行这些检查的方法中。

    为什么?

    它允许在我们发布之前进行完整性检查。

    这意味着,调用和使用的方法,只有在调试模式构建时才应该编译。当代码在Release 模式下构建时,它永远不会被调用或编译到exe中;因此,不在发布代码中进行开发检查,因为它很可能不会看到 开发 类型失败。

    例如

    [ConditionalAttribute("DEBUG")]
    private void CheckIfEligible(DateTime start, Datetime end)
    {
        if (DateTime.Compare(DateTime.Now, startTime) > 0)
            Console.WriteLine($"{Environment.Newline}ERROR: choose a later date");
    
        if (start > end)
          Console.WriteLine($"{Environment.Newline}ERROR: choose a earlier date");
    
    }
    

    然后在你的代码中做这样的事情。

    public void MyOperation()
    {
       ....
       CheckIfEligible(myStartTime, myEndTime);
    
       // Normal processing no extra checks needed
       If () ...
    
    }
    

    这允许您在不影响最终结果的情况下执行此过程似乎建议您想要的完整性检查。

    【讨论】:

    • 嘿,谢谢!我实际上只是通过使用自定义异常类解决了第一个问题。但由于“CheckIfEligible”是一个布尔值,我需要返回 false 但它无法访问。我该如何解决?谢谢编辑:实际上只是通过将 return 语句放入 catch 来修复它!非常感谢您的回答!
    • 现在您要求我们设计您的程序; SO不是这样做的平台。我们可以提供建议(这是),这取决于程序员是否使用。如果这篇文章有帮助,请标记它。如果它也是 answer,则将其标记为此类。无论如何,您只需要在每个帖子中就一个问题而不是设计失败的问题提出一个问题。 :-)
    • 如果我超出了网站的目标,我深表歉意。多亏了你和其他人的帮助,我最终还是自己做到了,但没有任何人真正设计我的程序,所以,谢谢:)
    • 我们都必须学习,你和我的区别在于没有可以寻求帮助的互联网(有但没有这种形式)。继续问。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多