关于在哪里放置 Try 和 Catch 语句的问题

发布于 2024-10-17 09:06:01 字数 1726 浏览 3 评论 0原文

我使用 try 和 catch 语句作为保持代码运行而不崩溃的简单方法(我会将所有内容包装在一次大尝试中)。最近,我想开始更正确地使用 try 和 catch 语句。举个例子,我有以下问题:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        try{
            if(numberOfShirikins == 0){
                throw new System.ArgumentException("Invalid number of shirikins");
            }

            //Throw shirikin
        }
        catch(ArgumentException e){
            MessageBox.Show(e.Message);
        }
    }
}

在上面的 Ninja 类中,我的 ThrowShirikin 方法的全部内容都包含在 try 循环中。由于输入错误只有一次机会(在本例中,当 numberOfShirikins == 0 时),因此 try 循环中不应该只包含检查此错误的代码行吗?见下文:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        bool errorsExist = false;
        try{
            if(numberOfShirikins == 0){
                errorsExist = true;
                throw new System.ArgumentException("Invalid number of shirikins");
            }
        }
        catch(ArgumentException e){
            MessageBox.Show(e.Message);
        }

        if(!errorsExist){
            //Throw shirikin
        }
    }
}

^但是我这里的东西似乎有点笨重。关于我如何理解 try catch 语句的使用有什么建议和意见吗?谢谢!

编辑:

或者我可以这样做,这样如果 numberOfShirikins 的值无效,则 //Throw shirikin 代码永远不会执行?:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        try{
            if(numberOfShirikins == 0){
                throw new System.ArgumentException("Invalid number of shirikins");
                return;
            }
        }
        catch(ArgumentException e){
            MessageBox.Show(e.Message);
        }

        //Throw shirikin
    }
}

I've used try and catch statements as an easy way to keep my code running without things crashing (I would wrap everything in a big try). Recently, I've wanted to start using try and catch statements more correctly. Here as an example I have questions about:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        try{
            if(numberOfShirikins == 0){
                throw new System.ArgumentException("Invalid number of shirikins");
            }

            //Throw shirikin
        }
        catch(ArgumentException e){
            MessageBox.Show(e.Message);
        }
    }
}

In the above Ninja class, the entire contents of my ThrowShirikin method is contained in a try loop. Since there is only one opportunity for an input error (in this case, when numberOfShirikins == 0), shouldn't only the lines of code that check for this be contained in the try loop? See below:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        bool errorsExist = false;
        try{
            if(numberOfShirikins == 0){
                errorsExist = true;
                throw new System.ArgumentException("Invalid number of shirikins");
            }
        }
        catch(ArgumentException e){
            MessageBox.Show(e.Message);
        }

        if(!errorsExist){
            //Throw shirikin
        }
    }
}

^But what I have here seems a bit clunky. Any suggestions and input on how I'm understanding the use of try catch statements? Thanks!

Edit:

Or I could do something like this so the //Throw shirikin code never executes if there is an invalid value for numberOfShirikins?:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        try{
            if(numberOfShirikins == 0){
                throw new System.ArgumentException("Invalid number of shirikins");
                return;
            }
        }
        catch(ArgumentException e){
            MessageBox.Show(e.Message);
        }

        //Throw shirikin
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

把梦留给海 2024-10-24 09:06:02

没有真正的理由在相同的方法中捕获异常。没有:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        if(numberOfShirikins == 0){
            MessageBox.Show(e.Message);
            return;
        }

        //...
    }
}

There is no real reason to catch exceptions in the same method like that. Go without:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        if(numberOfShirikins == 0){
            MessageBox.Show(e.Message);
            return;
        }

        //...
    }
}
神魇的王 2024-10-24 09:06:02

方法不应该捕获它自己抛出的异常 - 生成它们很好,但要明白它们很昂贵并且首选正常的流程控制(更容易推理等等)。

此外,在上面的示例中,errorsExist 永远不会设置为 true - 应该将其放在 catch 块中,而不是直接放在抛出异常的位置下。这将终止正常的程序流程。

重述一下,方法看起来像这样。

public void ThrowShirikin(int numberOfShirikins) {
    if(numberOfShirikins == 0){
        throw new System.ArgumentException("Invalid number of shirikins", "numberOfShirikins");
    }

    //Throw shirikin
}

由调用该方法的类来决定如何处理异常。

A method should not be capturing exceptions that it throws itself - it's fine to generate them, but understand that they are expensive and that normal flow control is preferred (it's easier to reason about and such).

Further, in the above example, errorsExist will never be set to true - that should be put in your catch block rather than directly under where you're throwing an exception. That terminates the normal program flow.

Restated, method would look like this.

public void ThrowShirikin(int numberOfShirikins) {
    if(numberOfShirikins == 0){
        throw new System.ArgumentException("Invalid number of shirikins", "numberOfShirikins");
    }

    //Throw shirikin
}

It would be up to the class calling the method to decide what to do with the exception.

人心善变 2024-10-24 09:06:02

两者都不是一个好主意。抛出异常并以相同的方法捕获它并显示该类的表单对话框是没有意义的。

只有应包含 GUI 代码的类才是 GUI 中的类。

在你的情况下,我也不会使用异常,我会使用布尔返回值:

public bool ThrowShirikin(int numberOfShirikins){
            if(numberOfShirikins == 0){
                return false;
            }
            //throw
            return true;
    }

异常应该用于特殊情况,而不是一般情况。

另外,请注意,第二种方式中的 errorsExist = true; 代码永远不会被调用,因为它位于 throw 语句下方。

Neither is a good idea. There is no sense in throwing an exception and catching it in the same method and to display a forms dialog from that class.

Only classes that should contain GUI code are the ones in your GUI.

In your case, I wouldn't use an exception either, I would use a boolean return value:

public bool ThrowShirikin(int numberOfShirikins){
            if(numberOfShirikins == 0){
                return false;
            }
            //throw
            return true;
    }

Exceptions should be used for exceptional cases, not the general, which this would be.

Also, be aware that the errorsExist = true; code in your second way will never be called as it is below a throw statement.

谁对谁错谁最难过 2024-10-24 09:06:02

当你抛出异常时,你基本上是在说:“这是一种异常情况,我不知道如何处理(或者更高层的另一种方法会更好地了解应该如何处理)”

那么该方法是什么你刚刚发布的内容是:“当我被要求扔 0 个手里剑时,我不知道该怎么办。实际上我撒谎了,我将显示一个消息框”

要么一起跳过异常并显示消息(并不理想,但比抛出的更好),或者只是抛出异常并在 UI 代码的更高位置捕获它。如果您想专门处理这一特定异常,您可能需要创建自己的异常类型。

When you throw an exception, you're basically saying: "This is an exceptional situation that I don't know how to handle (or another method higher up would have a better idea of how this should be handled)"

So what the method you just posted is saying then is: "I don't know what to do when I'm asked to throw 0 shurikens. Actually I lied, I'm going to show a message box"

Either skip the exception all together and show the message (not ideal, but better than throwing than what you have), or just throw the exception and catch it higher up in the UI code. You may want to create your own exception type if you want to handle this specific one specially.

苍白女子 2024-10-24 09:06:02

IMO - 异常实际上是代码中的异常情况 - 即无法预期的情况和/或错误可能在真正的异常情况下出错的情况。

如果上面显示的代码片段,有一个 numberOfShirikins == 0 不是一个异常条件,它是一个正常的参数检查

所以,我将重构代码:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        bool errorsExist = false;
        try{
            if(numberOfShirikins == 0){ showUserMessage("Invalid number of shirikins", MessageType.Information); }
        }
        catch(ArgumentException e){
            showUserMessage(e.Message, MessageType.Exception, e);
        }

        if(!errorsExist){
            //Throw shirikin
        }
    }
   private showUserMessage(string message, MessageType type, Exception ex = null){
        MessageBox.Show(message);
   }

}

一旦完成,你会发现捕获异常实际上没有任何附加值,所以我们也许可以编写一个通用的异常处理程序来显示异常并显示异常。让你的代码正常流通。

现在,我的代码如下所示:

public class Ninja{
        Ninja(){
        }

        public void ThrowShirikin(int numberOfShirikins){
                if(numberOfShirikins == 0){ showUserMessage("Invalid number of shirikins", MessageType.Information); return; }
                else{ /* do something here */ }
        }

另一方面,如果 numberOfShirikins == 0 是一个异常条件,那么我将编写一个自定义异常,代码如下:

public class Ninja{
        Ninja(){
        }

        public void ThrowShirikin(int numberOfShirikins){
                if(numberOfShirikins == 0){ throw NumberOfShirikinsException(); }
                else{ /* do something here */ }
        }

IMO - an Exception is really an exceptional condition in your code - i.e. conditions which cannot be anticipated and/or cases where the error can error in truly exceptional conditions.

If the code snippet you have shown above, have an numberOfShirikins == 0 is not an exceptional condition, it is a normal argument check

So, I would re-factor the code to:

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
        bool errorsExist = false;
        try{
            if(numberOfShirikins == 0){ showUserMessage("Invalid number of shirikins", MessageType.Information); }
        }
        catch(ArgumentException e){
            showUserMessage(e.Message, MessageType.Exception, e);
        }

        if(!errorsExist){
            //Throw shirikin
        }
    }
   private showUserMessage(string message, MessageType type, Exception ex = null){
        MessageBox.Show(message);
   }

}

Once this is done, you will find that there is really no value addition done to catching the exception, so we might be able to write a generic exception handler to show exception & let your code flow through normally.

Now, my code would look like:

public class Ninja{
        Ninja(){
        }

        public void ThrowShirikin(int numberOfShirikins){
                if(numberOfShirikins == 0){ showUserMessage("Invalid number of shirikins", MessageType.Information); return; }
                else{ /* do something here */ }
        }

On the other hand, if the numberOfShirikins == 0 is an exceptional condition, then I will write a custom Exception with the code as:

public class Ninja{
        Ninja(){
        }

        public void ThrowShirikin(int numberOfShirikins){
                if(numberOfShirikins == 0){ throw NumberOfShirikinsException(); }
                else{ /* do something here */ }
        }
々眼睛长脚气 2024-10-24 09:06:02

如果你能避免抛出异常,你就应该这样做。它们花费大约 1000-4000 个时钟周期。

If you can avoid to throw exceptions, you should. They cost about 1000-4000 clock cycles.

∝单色的世界 2024-10-24 09:06:01

当您抛出像 ArgumentException 这样的异常时,您不应该在方法中捕获它们。根据您的方法将此工作交给客户。

When you throw exceptions like ArgumentException you shouldn't catch them in your method. Give this work to client for your method.

爱本泡沫多脆弱 2024-10-24 09:06:01

看起来 try/catch 的存在只是为了捕获您选择创建和抛出的异常,然后捕获它只是为了向用户弹出一个消息框。然后您根据错误情况选择继续或不继续。

消除trycatch。消除消息框。 Do 为无效参数抛出异常。让函数的调用者决定是否要捕获以及如何处理。除了确定哪些内容有效、哪些内容无效之外,您的 Ninja 类不应做出这些决定。

if (numberOfShirikins == 0)
    throw new ArgumentException("...");

// rest of your shirikin throwing code

It looks like the try/catch only exists to catch an exception you are choosing to create and throw, and then you catch it just to pop a message box to the user. Then you choose to either continue or not based off the error condition.

Eliminate the try and the catch. Eliminate the message box. Do throw an exception for an invalid argument. Let the caller of the function determine if they want to catch and how they want to handle. Your Ninja class should not be making these decisions beyond identifying what is valid and what is not.

if (numberOfShirikins == 0)
    throw new ArgumentException("...");

// rest of your shirikin throwing code
迷荒 2024-10-24 09:06:01

你不应该以这种方式捕获异常。只捕获您实际上可以处理的异常。

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
            if(numberOfShirikins <= 0){
                throw new System.ArgumentException("Invalid number of shirikins");
            }
        //Throw shirikin
    }
}

我建议您开始编程时不要使用 try/catch。然后修复您看到的任何异常,不要隐藏它们。

You should never catch exceptions in this way. Only catch exceptions that you can actually handle.

public class Ninja{
    Ninja(){
    }

    public void ThrowShirikin(int numberOfShirikins){
            if(numberOfShirikins <= 0){
                throw new System.ArgumentException("Invalid number of shirikins");
            }
        //Throw shirikin
    }
}

I suggest that you start programming without ever using try/catch. Then fix any exceptions you see, don't hide them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文