使用goto的最佳实践

时间:2011-03-30 10:21:24

标签: c# .net goto

在此代码中使用goto是否正确?还有其他选择吗?

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;
});

5 个答案:

答案 0 :(得分:17)

如果您希望返回当前填充的列表,则可以将goto exit;替换为return null;return partnerhip;。 (我认为合作伙伴关系是一个很酷的合作伙伴?)

答案 1 :(得分:7)

我会说不。

我从2001年开始使用C#进行编程,从未使用过goto!

如果您希望代码中出现“短路”退出,为什么不替换

goto exit:

return partnership

答案 2 :(得分:5)

在我看来,

goto和“最佳实践”是相互排斥的(并且可能/希望大多数其他人也是如此)。需要goto表示错误的代码设计。在您的情况下,解决方案似乎很简单:我认为您只需要goto exit替换return partnerhip并删除标签exit:。 (它应该是“伙伴关系”而不是“伙伴关系”吗?)

答案 3 :(得分:1)

你最后在做的是从读者那里加载合同。如果你用一个简单的if语句明确表达这个意图,那就更好了。

将结束更改为:

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

return partnerhip;

虽然看起来你只是忽略了合同清单......它没有做任何事情。除非创建一个新的BEContractB2B类有一些全局副作用(坏消息),你可以完全摆脱它......

将第一个转到

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

由于这就是你正在做的事情,你应该明确表示你将返回null。

答案 4 :(得分:0)

我发现以下情况,当goto有点有用时:When To Use Goto When Programming in C。但是“从不使用GOTO ”是我在大学学到的第一件事,因此我从未使用它(至少不是在C,C ++,C#,Java,......)。

GOTO最大的问题是,如果你阅读了一些方法,你就看不出它可以被调用的地方了。例如:

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

......听起来不错。但是如果在分割块之后存在跟随GOTO的话,你写了0分割崩溃:

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

...如果在分割块之前有GOTO,则为null异常崩溃:

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

......这只是一个例子,GOTO引发了更多有争议的情况。所以请忘记GOTO,人们(包括您)在阅读您的代码时会更快乐。

使用“返回合作关系”;而不是你的goto。