4

众所周知,不应使用 StringBuilder 代替少量串联:

string s = "Hello";
if (greetingWorld)
{
    s += " World";
}

s += "!";

然而,在相当大的循环中,StringBuilder 是显而易见的选择:

string s = "";
foreach (var i in Enumerable.Range(1,5000))
{
    s += i.ToString(); // <- bad idea!
}

Console.WriteLine(s);

是否有一种工具可以在原始 C# 源代码或已编译程序集上运行,以识别代码中String.Concat被调用的位置?(如果您不熟悉,s += "foo"则映射到String.ConcatIL 输出中。)显然,我无法实际搜索整个项目并评估每个项目+=以确定左值是否为字符串。

理想情况下,它只会指出 for/foreach 循环内的调用,但我什至会忍受所有的误报 String.Concat。另外,我知道有一些重构工具会自动重构我的代码以使用StringBuilder,但我现在只对确定Concat使用情况感兴趣。

我经常在我的代码上运行 Gendarme 和 FxCop,但这些工具都不能识别我所描述的内容。但是,正如@Cristian 指出的那样,旧版本的 FxCop 曾经对此进行检查。也许有一种方法可以从旧版本的 FxCop 中提取该规则并告诉新版本(1.36)使用它?

4

2 回答 2

3

也许 NDepend CQL(代码查询语言)足以表达这一点。不确定是否是这样。

于 2010-05-10T16:51:44.243 回答
0

FxCop 对此提出了一些建议。检查这篇文章

例如根据此代码中的文章:

static string BadConcatenate(string[] items)
{
    string strRet = string.Empty;

    foreach(string item in items)
    {
        strRet += item;
    }

    return strRet;
}

FxCop 报告

"Change StringCompareTest.BadConcatenate(String[]):String to use StringBuilder 
  instead of String.Concat or +

编辑

看起来规则CA1807已被删除,因为噪声高或分析不再适用。看起来编译器并没有自动替换它,在同一个链接中,他们更详细地阐述了这两种方法的性能。

于 2010-05-10T17:23:47.933 回答