0

我有一些结构如下的代码:

if (someStatement)
{
    //...
    if (SomeOtherStatement)
    {
        //..., possibly more cases like this
    }
    else
    {
        //goto warning;
        //would otherwise repeat
        //the MessageBox.Show here
    }
}
else
{
    //goto warning;
}
//...
warning:
MessageBox.Show("some warning");

由于我讨厌复制代码,这是 goto 为数不多的有用应用程序之一,还是我可以使用更好的结构?

4

9 回答 9

5

那这个呢?

if (someStatement)
{
    //...
    if (SomeOtherStatement)
    {
        //..., possibly more cases like this

        return; // in the inner-most case
    }
}

MessageBox.Show("some warning");
于 2009-12-03T10:00:39.380 回答
2

是的,但前提是goto您的意思是“创建一个函数并多次调用它”。

于 2009-12-03T10:00:53.253 回答
1

最好的方法取决于其余代码的样子。如果显示的代码是该方法中的最后一个代码:

if(someStatement) {
    // ...
    if(SomeOtherStatement)
    {
        // a couple of lines of code
        return; // !
    }
}

MessageBox.Show("someWarning");

如果没有,你可能不得不反驳这样的事情:

if(someStatement) {
    // ...
    if(SomeOtherStatement)
    {
        // a couple of lines of code
    }
    else 
    {
        showWarning("not someOtherStatement");
    }
}
else
{
    showWarning("not someStatement");
}
于 2009-12-03T10:03:38.630 回答
0

我认为 goto 是个坏主意。如果你必须跳,抛出一个异常,正如 joshcomley 所建议的那样;如果您只想输出警告消息,但不跳转而继续,请调用方法。

于 2009-12-03T10:30:32.140 回答
0

由于(从 FrameWork 1.1 开始)逻辑和“&&”:“仅在必要时评估其第二个操作数。”

有什么问题:

if(someStatement && someOtherStatement)
{
       // more whatever
}
else
{
       // raise an exception, call a method, show messagebox, whatever
}

如果第一个子句评估为真,则取决于逻辑评估的复杂性:并且您可能会实施许多其他测试,其中任何数量都可能导致错误:您希望以相同的方式处理所有这些:I' d 认为必须引发特定异常,调用方法来处理错误,或者将整个事情放在 try-catch 块中(如果有很多代码,这可能会非常难看)。

如果可以合理地假设错误的可能性在 99% 的代码被调用的情况下非常遥远,我会使用一种低调的、肮脏的偷偷摸摸的方法:我会设置一个布尔标志来反映错误状态:评估它在完成复杂的代码块时,并做需要做的事情:当然,如果您的代码由于这些内部评估而在某处分支:那将不是一件好事。

于 2009-12-03T10:25:45.077 回答
0

异常是在 .NET 中处理错误、抛出异常的正确方法,但要明智地使用它们:

try
{
    if (someStatement)
    {
        //...
        if (SomeOtherStatement)
        {
            //..., possibly more cases like this
        }
        else
        {
            throw new MyException();
            //would otherwise repeat
            //the MessageBox.Show here
        }
    }
}
catch(MyException e)
{
    MessageBox.Show(e.Message);
    // log the exception, if necessary
}
finally
{
    // tidy up
}

除了你会得到一个强类型的答案,你可以很容易地在日志系统中实现错误。

于 2009-12-03T10:05:03.900 回答
0

如果您要像您一样进入一个令人讨厌的错误测试语句,那么您可能需要考虑用单个 try/catch 包装它,并从 if 语句中抛出适当的应用程序特定异常,并捕获那些特定异常在 catch 块中,让所有其他人继续被捕获到更远的链上。

于 2009-12-03T10:06:27.843 回答
0

我个人认为集中式错误处理是“几乎唯一可以接受 goto 的情况”。但是,为了获得更好的结构,我会将标签完全放在 else 之外,在函数的最后。

于 2009-12-03T09:59:23.283 回答
0

您是否在两行都显示相同的错误消息?然后,您应该编写一个仅调用该行并在两种情况下都调用该函数的函数。

if (someStatement)
{
    //...
    if (SomeOtherStatement)
    {
        //..., possibly more cases like this
    }
    else
    {
        showError();
    }
}
else
{
    showError();
}

顺便说一句:这是一个不好的例子,它可以通过一个 else-branch 捕获错误来解决。这是一个更好的:

if (!doSomething())
{
    showError();
}
doSomethingElse();
if (!anotherCall())
{
    showError();
}
于 2009-12-03T10:00:50.897 回答