gpt4 book ai didi

c# - 在C#中处理 “loop initialization”的其他方式

转载 作者:IT王子 更新时间:2023-10-29 04:29:19 26 4
gpt4 key购买 nike

首先,我同意我同意goto语句在很大程度上不受现代编程语言中更高层次的构造的影响,并且在有合适的替代方法时不应该使用goto语句。

我最近重新阅读了史蒂夫·麦康奈尔(Steve McConnell)的Code Complete的原始版本,却忘记了他对常见编码问题的建议。我几年前刚入门时就读过它,但没想到我意识到该食谱有多有用。编码问题如下:在执行循环时,您通常需要执行循环的一部分以初始化状态,然后使用其他逻辑执行循环,并以相同的初始化逻辑结束每个循环。一个具体的示例是实现String.Join(delimiter,array)方法。

我认为每个人首先要解决的问题就是这个。假设定义了append方法以将参数添加到您的返回值中。

bool isFirst = true;
foreach (var element in array)
{
if (!isFirst)
{
append(delimiter);
}
else
{
isFirst = false;
}

append(element);
}

注意:对此的略微优化是删除else并将其放在循环的末尾。分配通常是一条指令,与else等效,并且将基本块的数量减少1,并增加主要部分的基本块大小。结果是在每个循环中执行一个条件以确定是否应添加定界符。

我也已经看到并使用其他方法来处理此常见循环问题。您可以先在循环外部执行初始元素代码,然后从第二个元素到最后执行循环。您还可以更改逻辑,以始终将元素追加到定界符之后,一旦循环完成,您只需删除最后添加的定界符即可。

后一种解决方案往往是我更喜欢的解决方案,因为它不重复任何代码。如果初始化序列的逻辑发生了变化,则无需记住在两个位置进行修复。但是,它确实需要额外的“工作”才能执行某些操作然后撤消它,这至少会导致额外的cpu周期,并且在许多情况下(例如我们的String.Join示例)也需要额外的内存。

当时我很高兴阅读此构造
var enumerator = array.GetEnumerator();
if (enumerator.MoveNext())
{
goto start;
do {
append(delimiter);

start:
append(enumerator.Current);
} while (enumerator.MoveNext());
}

这样做的好处是您没有重复的代码,也没有其他工作。您将在执行第一个循环的一半时开始循环,这就是您的初始化。您仅限于使用do while构造来模拟其他循环,但翻译起来很容易,阅读起来并不困难。

所以,现在的问题。我很高兴去尝试将其添加到我正在处理的代码中,发现它不起作用。在C,C++,Basic中可以很好地工作,但是事实证明,在C#中,您不能跳转到不是父范围的其他词法范围内的标签。我感到非常失望。因此,我想知道,在C#中处理这种非常常见的编码问题(我主要在字符串生成中看到)的最佳方法是什么?

要更具体地说明需求:
  • 不要重复代码
  • 不要做不必要的工作
  • 不要比其他代码
  • 慢2至3倍
  • 可读

  • 我认为可读性是我说过的唯一可能会受苦的东西。但是,它在C#中不起作用,那么下一件最好的事情是什么?

    *编辑*
    由于某些讨论,我更改了性能标准。在这里,性能通常不是限制因素,因此,更正确的目标应该是避免不合理,而不要成为最快。

    我不喜欢我建议的替代实现的原因是因为它们要么重复代码,从而留出了更改一个部分的空间,而没有另一个部分,或者对于我通常选择的部分,则需要“撤消”该操作,这需要额外的思考和时间才能撤消该操作。你刚刚做了。特别是在使用字符串操作时,这通常会导致您因一个错误或无法解决一个空数组而试图撤消未发生的事情而感到无所适从。

    最佳答案

    对于您的特定示例,有一个标准解决方案:string.Join。这样可以正确添加定界符,因此您不必自己编写循环。

    如果您真的想自己编写此方法,则可以使用以下方法:

    string delimiter = "";
    foreach (var element in array)
    {
    append(delimiter);
    append(element);
    delimiter = ",";
    }

    这应该是相当有效的,我认为阅读是合理的。常量字符串“,”被插入,因此不会导致每次迭代都创建一个新的字符串。当然,如果性能对您的应用程序至关重要,则应该进行基准测试而不是猜测。

    关于c# - 在C#中处理 “loop initialization”的其他方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3596348/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com