【问题标题】:Use inner exceptions or create derived types of base exception使用内部异常或创建基本异常的派生类型
【发布时间】:2021-09-16 08:25:36
【问题描述】:

如果有一个方法调用了许多其他方法,并且它们都可以抛出从 ArgumentExceptions 到 EndOfStreamExceptions 的各种异常,最好做一个 catch all 并将其包装在您自己的异常中,然后设置内部异常,或者创建一个基类异常并抛出派生类型。如果抛出违反尽可能重用 BCL 异常的建议的派生类型。比如

public void A()
{
    if (someCondition)
    {
        throw new ArgumentException()
    }
}

public void B()
{
    if (anotherCondition)
    {
        throw new InvalidOperation()
    }
}

public void C()
{
    // Throws format exception
    int.Parse(x);
}

public void DoSomething()
{
    try
    {
        A();
        B();
        C();
    }
    catch(Exception ex)
    {
        throw new DoSomethingException("Could not complete DoSomthing"){ InnerException = ex};
    }
}

或者做类似的事情会更好

public void DoSomething()
{
    A();
    B();
    C();
    D();
}

public void A()
{
    if (someCondition)
    {
        throw new DoSomethingMissingArg()
    }
}

public void B()
{
    if (anotherCondition)
    {
        throw new DoSomethingCannotStart()
    }
}

public void C()
{
    // Throws format exception
    if (!int.TryParse(x))
    {
        throw new DoSomethingFormatException("x must be in y format");
    }
}

public class DoSomethingException: Exception
{

}

public class DoSomethingMissingArg: DoSomethingException
{
    public DoSomethingMissingArg(){ }
}

public class DoSomethingCannotStart: DoSomethingException
{
    public DoSomethingCannotStart(){ }
}

public class DoSomethingFormatException: DoSomethingException
{
    public DoSomethingFormatException(){ }
}

【问题讨论】:

    标签: c# exception


    【解决方案1】:

    这仅取决于您的调用者在捕获异常时是否可能需要该级别的详细信息。

    我的建议是先实施选项 1,然后,如果需要更多详细信息,请切换到以下选项 3:

    public void A()
    {
        if (someCondition)
        {
            throw new ArgumentException()
        }
    }
    
    ...    
    
    public void DoSomething()
    {
        try
        {
            A();
        }
        catch(ArgumentException ex)
        {
            throw new DoSomethingMissingArgException() { InnerException = ex };
        }
    
        try
        {
            B();
            C();
        }
        catch(Exception ex)
        {
            throw new DoSomethingException("Could not complete DoSomthing"){ InnerException = ex};
        }
    }
    

    方案3具有以下优点:

    • 它向后兼容选项 1,因为 DoSomethingMissingArgException 是一个 DoSomethingException。您可以根据需要添加更多异常子类同时保持向后兼容
    • 您仅在方法 DoSomething 中具有特定于 DoSomething 的异常逻辑,而不是分散在您的辅助方法周围,这些方法可以使用“自然”BCL 执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      相关资源
      最近更新 更多