使用 goto 的最佳实践

发布于 2024-10-28 04:44:24 字数 917 浏览 8 评论 0原文

这段代码中使用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;
});

Is it right to use goto in this code? 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;
});

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

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

发布评论

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

评论(5

迎风吟唱 2024-11-04 04:44:24

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

You can replace each goto exit; with return null; or return partnerhip; if you wish to return the currently populated list. (I assume a partnerhip is a cool partner?)

流年已逝 2024-11-04 04:44:24

我会说不。

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

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

goto exit:

return partnership

I would say no.

I've been programming in C# since 2001 and have never used goto!

If you want a "short circuit" exit in your code, why not replace the

goto exit:

with

return partnership
伤痕我心 2024-11-04 04:44:24

在我看来,goto 和“最佳实践”是相互排斥的(可能/希望大多数其他人也是如此)。需要 goto 表明代码设计有缺陷。就您而言,解决方案似乎很简单:我认为您只需将 goto exit 替换为 returnpartnership 并删除标签 exit: >。 (应该读“伙伴关系”而不是“伙伴关系”吗?)

goto and "best practice" are mutually exclusive, in my opinion (and probably/hopefully in that of most others, too). The need for a goto indicates a faulty code design. 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:. (Should it read "partnership" instead of "partnerhip"?)

寂寞美少年 2024-11-04 04:44:24

您最后要做的就是从阅读器加载合同(如果存在)。如果你用一个简单的 if 语句明确表达这个意图,那么读起来会更好。

将结尾更改为:

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

return partnerhip;

虽然看起来您只是忽略了合同列表...但它没有做任何事情。除非创建一个新的 BEContractB2B 类有一些全局副作用(坏消息),否则您可以将其全部删除。

将第一个 goto 更改为

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

因为这就是您正在做的事情,所以您应该明显地表明您将返回 null。

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.

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..

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.

荒人说梦 2024-11-04 04:44:24

我发现以下情况 goto 可能有点用: When To Use Goto When Programming in C。但是“永远不要使用 GOTO”是我在大学学到的第一件事,所以我真的从未使用过它(至少在 C、C++、C#、Java 等中没有使用过)。

GOTO 最大的问题是,如果你阅读一段方法,你看不到它是从哪里被调用的。例如:

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

...听起来不错。但是你写了 0-除法崩溃,如果除法块后面有以下 GOTO:

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

... 或者如果除法块之前有 GOTO 则空异常崩溃:

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

... 这只是一个例子,GOTO 会导致更多争议情况。因此,请忘记 GOTO,人们(包括您)在阅读您的代码时会更高兴。

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

I found following case when goto could be a bit useful: When To Use Goto When Programming in 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,...).

The biggest problem of GOTO is that if you read piece of method, you don't see from where it could be called. 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:

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 division;
// ... hundreds of lines ...
int a = 1;
division:
int b = 4 / a;

... this is only one example, GOTO leads to much more disputable situations. So please forget about GOTO and people (including you) will be happier during reading your code.

Use "return partnership;" instead of your goto's.

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