Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 错误处理的设计模式_C#_Asp.net_Design Patterns_Error Handling_Custom Error Handling - Fatal编程技术网

C# 错误处理的设计模式

C# 错误处理的设计模式,c#,asp.net,design-patterns,error-handling,custom-error-handling,C#,Asp.net,Design Patterns,Error Handling,Custom Error Handling,我在不同的项目中多次遇到这个问题,我想知道是否有比我通常使用的更好的解决方案 假设我们有一系列需要执行的方法,我们想知道其中一个方法是否出了问题并顺利地发生了变化(可能会撤消以前的任何更改…),我通常会执行以下操作(伪C,因为这是我最熟悉的): 我只是想知道(这是我的问题)是否有更好的方法来处理这种事情。我似乎最后写了很多if语句来描述一些看起来应该更流畅的东西 有人建议我在一组委托函数上进行循环,但我担心这会过度设计解决方案,除非有一种干净的方法。我认为您可能应该使用异常。注意:您通常应该只捕

我在不同的项目中多次遇到这个问题,我想知道是否有比我通常使用的更好的解决方案

假设我们有一系列需要执行的方法,我们想知道其中一个方法是否出了问题并顺利地发生了变化(可能会撤消以前的任何更改…),我通常会执行以下操作(伪C,因为这是我最熟悉的):

我只是想知道(这是我的问题)是否有更好的方法来处理这种事情。我似乎最后写了很多
if
语句来描述一些看起来应该更流畅的东西


有人建议我在一组委托函数上进行循环,但我担心这会过度设计解决方案,除非有一种干净的方法。我认为您可能应该使用异常。注意:您通常应该只捕获应用程序中“顶层”的异常

private void TopLevelMethod()
{
    try
    {
        SomeMethod();
    }
    catch (Exception ex)
    {
        // Log/report exception/display to user etc.
    }
}

private void SomeMethod()
{
    TestPartA();
    TestPartB();
    TestPartC();
    TestPartD();
}

private void TestPartA()
{
    // Do some testing...
    try
    {
        if (somethingBadHappens)
        {
            throw new Exception("The error that happens");
        }
    }
    catch (Exception)
    {
        // Cleanup here. If no cleanup is possible, 
        // do not catch the exception here, i.e., 
        // try...catch would not be necessary in this method.

        // Re-throw the original exception.
        throw;
    }
}

private void TestPartB()
{
    // No need for try...catch because we can't do any cleanup for this method.
    if (somethingBadHappens)
    {
        throw new Exception("The error that happens");
    }
}

在我的示例中,我使用了内置的System.Exception类;您可以创建自己的派生异常类,也可以使用从System.exception派生的内置异常类。

我试图坚持一个称为“Fail Fast”的原则;方法应该在应该失败时失败,并立即返回错误的详细信息。然后,调用方法会做出相应的响应(将异常重新抛出给调用方,记录详细信息,如果是UI绑定的方法,则显示错误,等等):-

但是,这并不意味着使用异常来控制应用程序的流。在您能够处理的情况下仅仅提出一个例外通常是不好的做法:-

在您的情况下,我会将您的代码重新编写为(例如):-


您可以尝试查看示例中的,您可以创建一个
ITestRule
接口,其中包含一个名为
CheckRule()
的方法,该方法将更新消息并返回
bool
。然后,您将为要测试的每个规则创建一个接口实现,并将该类添加到
列表
对象中。根据上面的Redmondo示例,我将更改为以下内容:

var discountRules =
                new List<ITestRule>
                    {
                        new TestPartA(),
                        new TestPartB(),
                        new TestPartC(),
                        new TestPartD(),
                    };
var贴现=
新名单
{
新建TestPartA(),
新的TestPartB(),
新的TestPartC(),
新的TestPartD(),
};

然后将新的
列表
传递给一个计算器,该计算器将遍历每个类并运行
CheckRule()
方法

如果这些是真正的错误,那么您可能应该抛出异常;谢谢你。我从未想过抛出我自己的异常/重新抛出异常,这几乎涵盖了所有场景。答案与ShellShock几乎相同,只是稍微慢一点!我喜欢快速失败的原则;非常有价值的阅读。来自msdn:“您应该从Exception类而不是ApplicationException类派生自定义异常。您不应该在代码中引发ApplicationException异常,并且您不应该捕获ApplicationException异常,除非您打算重新引发原始异常。”这将起作用(我将来可能需要这样的东西),但我想我会为我需要的东西过度设计而感到内疚。
private bool SomeMethod()
{
    bool success = false;

    try
    {
        TestPartA();
        TestPartB();
        TestPartC();
        TestPartD();

        success = true;
    }
    catch (Exception ex)
    {
        LogError(ex.Message);
    }

    //... some further tests: display the error message somehow, then:
    return success;
}

private void TestPartA()
{
    // Do some testing...
    if (somethingBadHappens)
    {
        throw new ApplicationException("The error that happens");
    }
}
var discountRules =
                new List<ITestRule>
                    {
                        new TestPartA(),
                        new TestPartB(),
                        new TestPartC(),
                        new TestPartD(),
                    };