简体   繁体   English

使用goto的最佳实践

[英]Best practice for using goto

Is it right to use goto in this code? 在这段代码中使用goto是正确的吗? Are there any alternatives? 还有其他选择吗?

return ExecuteReader(cmd, reader =>
{
    List<BEPartnership> partnerhip = null;

    //Partnership
    if (!((SqlDataReader) reader).HasRows)
        goto exit;

    partnerhip = 
        new List<BEPartnership>{new BEPartnership().GetFromReader(reader)};

    //Customers
    if (!reader.NextResult() && !((SqlDataReader) reader).HasRows)
        goto exit;

    foreach (BEPartnership p in partnerhip)
        p.Partner = new BECustomer().GetFromReader(reader);

    //Contracts
    if (!reader.NextResult() && !((SqlDataReader) reader).HasRows)
        goto exit;

    List<BEContractB2B> contracts = new List<BEContractB2B>();
    contracts.Add(new BEContractB2B().GetFromReader(reader));
    // contracts = new BEContractB2B().GetFromReader2(reader).ToList();

    exit:
    return partnerhip;
});

You can replace each goto exit; 你可以替换每个goto exit; with return null; return null; or return partnerhip; return partnerhip; if you wish to return the currently populated list. 如果您希望返回当前填充的列表。 (I assume a partnerhip is a cool partner?) (我认为合作伙伴关系是一个很酷的合作伙伴?)

I would say no. 我会说不。

I've been programming in C# since 2001 and have never used goto! 我从2001年开始用C#编程,从未使用过goto!

If you want a "short circuit" exit in your code, why not replace the 如果您想在代码中出现“短路”退出,为什么不替换

goto exit:

with

return partnership

goto and "best practice" are mutually exclusive, in my opinion (and probably/hopefully in that of most others, too). 在我看来, goto和“最佳实践”是相互排斥的(并且可能/希望也是大多数其他人的)。 The need for a goto indicates a faulty code design. 需要goto表示错误的代码设计。 In your case, the solution seems to be simple: I think you just have to replace goto exit by return partnerhip and to delete the label exit: . 在你的情况下,解决方案似乎很简单:我认为你只需要通过return partnerhip替换goto exit并删除标签exit: . (Should it read "partnership" instead of "partnerhip"?) (它应该是“伙伴关系”而不是“伙伴关系”吗?)

What you are doing at the end is loading contracts from the reader if it is there. 你最后在做的是从读者那里加载合同。 It reads much better if you make this intention explicit with a simple if statement. 如果使用简单的if语句明确表达此意图,则会更好。

Change the end to be : 将结束更改为:

if (reader.NextResult() || ((SqlDataReader) reader).HasRows)
{
    List<BEContractB2B> contracts = new List<BEContractB2B>();
    contracts.Add(new BEContractB2B().GetFromReader(reader));
}

return partnerhip;

Although it does appear you are just ignoring the contracts list... it isn't doing anything. 虽然看起来你只是忽略了合同清单......它没有做任何事情。 Unless creating a new BEContractB2B class has some global side effects (bad news), you could just get rid of it alltogether.. 除非创建一个新的BEContractB2B类有一些全局副作用(坏消息),你可以完全摆脱它...

Change the first goto to be 改变第一个转到

if (!((SqlDataReader) reader).HasRows)
    return null;

Since that is what you are doing, you should make it obvious you will return null. 既然这就是你正在做的事情,你应该明白你将返回null。

I found following case when goto could be a bit useful: When To Use Goto When Programming in C . 我发现以下情况,当goto可能有点用处: 何时使用Goto进行C语言编程时 But " Never use GOTO " was first thing I learned on University and so I really never used it (at least not in C,C++,C#,Java,...). 但是“ 从不使用GOTO ”是我在大学学到的第一件事,因此我从未使用它(至少不是在C,C ++,C#,Java,......)。

The biggest problem of GOTO is that if you read piece of method, you don't see from where it could be called. GOTO的最大问题是,如果你阅读了一些方法,你就看不出它可以被调用的地方。 For example: 例如:

int a = 1;
division:
int b = 4 / a;

... sounds OK. ......听起来不错 But you wrote 0-dividing crash, if there is following GOTO after the division block: 但是如果在分割块之后存在以下GOTO,则会写出0分割崩溃:

int a = 1;
division:
int b = 4 / a;
// ... hundreds of lines ...
a = 0;
goto division;

... Or null-exception crash if there is GOTO before the division block: ...如果在分区块之前有GOTO,则为null-exception崩溃:

goto division;
// ... hundreds of lines ...
int a = 1;
division:
int b = 4 / a;

... this is only one example, GOTO leads to much more disputable situations. ......这只是一个例子,GOTO引发了更多有争议的情况。 So please forget about GOTO and people (including you) will be happier during reading your code. 所以请忘记GOTO,人们(包括你)在阅读代码时会更开心。

Use "return partnership;" 使用“返回伙伴关系;” instead of your goto's. 而不是你的goto。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM