用于检测 String.Concat 的使用/滥用的工具(应使用 StringBuilder)

发布于 2024-09-01 03:51:48 字数 1023 浏览 7 评论 0原文

众所周知,不应使用 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" 会映射到 IL 输出中的 String.Concat。)显然,我无法实际搜索整个项目并评估每个 += 以确定左值是否是字符串。

理想情况下,它只会指出 for/foreach 循环内的调用,但我什至会忍受所有注意到 每个 String.Concat 的误报。另外,我知道有一些重构工具会自动重构我的代码以使用 StringBuilder,但我此时只对识别 Concat 用法感兴趣。

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

It's common knowledge that you shouldn't use a StringBuilder in place of a small number of concatenations:

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

s += "!";

However, in loops of a significant size, StringBuilder is the obvious choice:

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

Console.WriteLine(s);

Is there a tool that I can run on either raw C# source or a compiled assembly to identify where in the source code that String.Concat is being called? (If you're not familiar, s += "foo" is mapped to String.Concat in the IL output.) Obviously, I can't realistically search through an entire project and evaluate every += to identify whether the lvalue is a string.

Ideally, it would only point out calls inside a for/foreach loop, but I would even put up with all the false positives of noting every String.Concat. Also, I'm aware that there are some refactoring tools that will automatically refactor my code to use StringBuilder, but I am only interested in identifying the Concat usage at this point.

I routinely run Gendarme and FxCop on my code, and neither of those tools identify what I've described. However, as @Cristian pointed out, older versions of FxCop used to check for this. Maybe there's a way to extract just that rule from an old version of FxCop and tell the newer version (1.36) to use it?

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

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

发布评论

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

评论(2

赠意 2024-09-08 03:51:48

也许 NDepend CQL(代码查询语言)对此足够表达。不确定是否是这样。

Perhaps NDepend CQL (Code Query Language) is expressive enough for this. Not sure if it is though.

未蓝澄海的烟 2024-09-08 03:51:48

FxCop 对此的一些建议。检查 这篇文章

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

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

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

    return strRet;
}

FxCop reports

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

编辑

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

FxCop had some advices for that. Check this article

For instance according to the article in this code:

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

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

    return strRet;
}

FxCop reports

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

Edit

It looks like the rule CA1807 has been removed either because of high noise or no longer applicable analysis. And it looks like the compiler is not automatically replacing it, in the same link they elaborate more on the performance of both methods.

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