你使用(裸)C#代码块吗?

时间:2009-03-25 23:38:01

标签: c# coding-style

我已经用C#编程了一段时间了。我最近编写了一个例程,它发生在我身上,这是我第一次(我记得)故意使用裸代码块(即没有前面的控制流语句)。代码看起来像这样:

//...

var output = source.GetRawOutput();

{
    var fooItems = FooSource.GetItems();

    output = TransformA.TransformOutput(output, p =>
        {
            GetFooContent(p, fooItems.GetNext());
        });
}

{
    var barItems = BarSource.GetItems();

    output = TransformB.TransformOutput(output, p =>
        {
            GetBarContent(p, barItems.GetNext());
        });
}

return output;

我用这种方式构建代码主要是作为一个完整性检查,我不会意外地引用错误的变量(即混合barItems和fooItems)。我还发现代码更具可读性。我当然可以将代码分解为三种不同的方法,但我认为在这种情况下有点过分。

您在代码中使用裸代码块吗?为什么或为什么不呢?

7 个答案:

答案 0 :(得分:6)

如果查看代码,那两个块非常相似。我打赌他们可以重构成一个区块。

虽然这听起来不像答案,但确实如此。我想一般来说,如果你觉得想要使用这样的大括号,那么你正在处理一种情况,通过分解另一种方法或重构各种方法可以更好地处理这种情况。

总的来说,无论如何。

具体答案 - 不,一旦我擅长OO并限制我在一个单位做多少工作,我从未想过他们可能是个好主意。

编辑:使用相似的代码,它必须相当容易重构。我会试试一个重构器。对不起,如果我的语法错误,我真的不做c#而且Java没有闭包。

output = transform(FooSource, TransformA);
output = transform(BarSource, TransformB);  // I know output is overwritten, but
                // it is in the askers' example as well

transform(var itmSource, var transform) {
    var output=source.GetRawOutput();  // Sorry, you never said where source came from.

    var items = itmSource.GetItems();
    output=transform.TransformOutput(output, p =>
        {
            GetContent(p, items.GetNext()); // GetContent may need to be passed in
                                    // you didn't say where those calls came from.
                                 // See comments below
        });
    }
    return output;
}
像这样的重构不会节省太多的输入,但是它们会显示出一些很好的模式 - 比如FooSource和TransformA之间的关系(以及可能的getContent调用) - 它们应该被存储在一个对象和该对象应该传入,或类似的东西。 (很难从这个片段中分辨出来,通常重构需要比你给出的更广泛的代码视图)

请注意,它们也会强迫您考虑GetFooContent和GetBarContent。我敢打赌你喝了一品脱啤酒,这些啤酒非常相似,以至于它们可以被分解为一个方法调用,一个变量或两个传入或两个兄弟类中的方法。

由于这种关系总是出现并且总是改进你的类中的其他代码的方式,我相信这些重构绝对是强制性的,做这种重构比任何教我真正的OO更好。

答案 1 :(得分:2)

就个人而言,我不会这样做来构建代码。这在C ++中用于控制变量的范围并调用析构函数,但是当C#被垃圾收集时,我没有看到块的功能用法。

关于可读性的结构化,我相信你的方法要么小到不需要这些东西,要么应该分解成更小的方法。

答案 2 :(得分:1)

我发现,大多数时候我很想做这件事,我最好把它重构成一个单独的方法。举个例子 - 在这种情况下,看起来你可以使用一个方法来处理具有正确参数的两个裸代码块。

重构会使其更清晰,更易于维护。

答案 3 :(得分:1)

我从不使用它们,相反,我倾向于将代码块放入较小的方法中,使用描述性的名称,这样可以使意图更清晰。

我想在你提供它的例子中添加两个块,看起来很相似它可能是你用两个方法调用替换它们的一个改变,到一个为你工作的方法:

答案 4 :(得分:0)

我用它们来包装临时变量。例如,有时需要创建一个对象,设置一些变量,将它传递给一个函数,然后处理它。

答案 5 :(得分:0)

我几乎从不使用它们,就像其他人所说的那样。有一个边缘情况可供您使用:封闭块决定了编译器将变量捕获到闭包中的具体程度。

答案 6 :(得分:0)

裸代码块有一个非常有趣的用途:管理范围。

当我想要尽可能早地从GC收集一个非一次性的变量时,我必须在完成使用后立即从范围中删除它,所以我在裸块内创建变量,使用在那里,当执行离开块时,GC将看到变量超出范围,尽快收集它。

这对仅用于方法中的一些操作的大型列表很有用。如果方法的执行时间很长,那么建议在不再使用它们时删除列表。

PS:请注意,将它们设置为null将不起作用,因为当您将其设置为null时,您将引用它,因此GC将延迟收集而不是赶紧收集。