C# 使用goto的最佳实践

C# 使用goto的最佳实践,c#,.net,goto,C#,.net,Goto,在此代码中使用goto是否正确?还有其他选择吗 return ExecuteReader(cmd, reader => { List<BEPartnership> partnerhip = null; //Partnership if (!((SqlDataReader) reader).HasRows) goto exit; partnerhip = new List<BEPartnership>

在此代码中使用
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;
});
returnexecutereader(cmd,reader=>
{
列表伙伴关系=空;
//伙伴关系
if(!((SqlDataReader)reader).HasRows)
转到出口;
伙伴关系=
新列表{new BEPartnership().GetFromReader(reader)};
//顾客
if(!reader.NextResult()&&((SqlDataReader)reader).HasRows)
转到出口;
foreach(BEP合伙制)
p、 Partner=new BECustomer().GetFromReader(读卡器);
//合同
if(!reader.NextResult()&&((SqlDataReader)reader).HasRows)
转到出口;
列表合同=新列表();
contracts.Add(新的BEContractB2B().GetFromReader(reader));
//contracts=new BEContractB2B().GetFromReader2(reader.ToList();
出口:
回归伙伴关系;
});

您可以替换每个
转到退出
返回空值
返回合作伙伴关系如果要返回当前填充的列表。(我认为合作伙伴关系是一个很酷的伙伴?

我会说不

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

如果您希望代码中存在“短路”出口,为什么不更换

goto exit:


goto
和“最佳实践”在我看来是相互排斥的(在大多数其他人看来也是如此)。需要
goto
表示代码设计有缺陷。在您的情况下,解决方案似乎很简单:我认为您只需将
转到退出
替换为
返回合作关系
,并删除标签
退出:
。(它应该读“partnership”而不是“partnership”?)

如果有,你最后要做的是从读卡器加载合同。如果您用一个简单的if语句来明确这一意图,那么读起来会更好

将端点更改为:

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

return partnerhip;

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

我发现以下情况下,goto可能有点有用:。但是“<强>永远不要使用Goto < /Stand >是我在大学里学到的第一件事,所以我从来没有真正使用过它(至少在C、C++、C、java、……中没有)。 GOTO最大的问题是,如果你阅读了一段方法,你就看不到从哪里可以调用它。例如:

int a = 1;
division:
int b = 4 / a;
。。。听起来不错。但是您编写了0分割崩溃,如果分割块后有以下转到:

int a = 1;
division:
int b = 4 / a;
// ... hundreds of lines ...
a = 0;
goto division;
goto division;
// ... hundreds of lines ...
int a = 1;
division:
int b = 4 / a;
。。。如果除法块前有GOTO,则为空异常崩溃:

int a = 1;
division:
int b = 4 / a;
// ... hundreds of lines ...
a = 0;
goto division;
goto division;
// ... hundreds of lines ...
int a = 1;
division:
int b = 4 / a;
。。。这只是一个例子,后藤会导致更多有争议的情况。因此请忘记GOTO,人们(包括您)在阅读您的代码时会更快乐。


使用“return partnership;”而不是goto。

最佳做法是:不要使用goto@史蒂文:这太简单了。有些情况下,使用goto是非常有用的。有些情况下,使用goto是非常无用的。@Mongus:每次你做一个循环,编译器都会将一个goto放入已编译的IL中。IL只有三个基本的控制流:抛出、转到和返回。几乎每件事都是要做的。结构化编程的要点是选择比goto更有意义的控制流,而不是完全避免分支。编写简短的函数,您将永远不需要
转到
。实际上,您的第二个示例甚至无法编译。首先,
a
是一种值类型,不能为
null
。其次,编译器将检测
inta=1不可访问,首先发出不可访问代码警告,然后使用未分配的局部变量错误,这将导致代码无法编译。