ReSharper 为 lambda 表达式中的变量名提供“@”前缀

Posted

技术标签:

【中文标题】ReSharper 为 lambda 表达式中的变量名提供“@”前缀【英文标题】:ReSharper gives an "@" prefix to a variable name in a lambda expression 【发布时间】:2012-03-07 10:53:02 【问题描述】:

在使用 ReSharper 时,它会自动添加一个 @,为什么?

public static string RemoveDiacritics(this string input)

    if (string.IsNullOrEmpty(input)) return input;
    var normalizedString = input.Normalize(NormalizationForm.FormD);
    var stringBuilder = new StringBuilder();
    foreach (var value in normalizedString.Select(value => 
        new value, unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(value))
            .Where(@t => @t.unicodeCategory != UnicodeCategory.NonSpacingMark)
            .Select(@t => @t.value)) stringBuilder.Append(value);
    return (stringBuilder.ToString().Normalize(NormalizationForm.FormC));

【问题讨论】:

我也想知道为什么。我猜是为了提高可读性的约定,但我可能是错的。 使用string.Concat,您可以取消StringBuilder 和循环。 【参考方案1】:

@ 符号允许您为变量名使用保留关键字。如@class。我认为 Resharper 这样做是为了安全。

在这种情况下,它是不需要的,它没有任何作用。

【讨论】:

安全...可能,但在 r# hq 有一种懒惰的味道,这不是我通常与 r# 相关的东西。 我注意到 R# 有时会在 group 之前添加 @,即使在没有必要的情况下也是如此。 group 是上下文关键字,因此 @ 有时是必要的,但 R# 似乎无法识别这些情况,只是将 @ 始终放在那里。 @svick:我不确定它是否应该识别这些情况。放入 @ 符号是防止未来维护者将其与(无效的)上下文关键字混淆的好方法。 重要的是要强调@不会包含在变量名中,这意味着@group仍然可以使用group访问【参考方案2】:

您必须询问 resharper 的实施者才能确定,但​​我可以做出有根据的猜测。它们可能是面向未来的

自 C# 1.0 发布以来,编译器团队为 C# 添加了 21 个新的上下文关键字;当它们出现在某些位置时,编译器将它们视为关键字,否则将其视为普通标识符。例如,yield 只是出现在return 之前的关键字。

当 resharper 工具为您生成代码时,他们不知道该代码是否会在某些假设的 C# 6 中编译,该 C# 6 在某些上下文中使用 t 作为上下文关键字。因此,他们通过将@ 放在其前面,先发制人地喊出“此标识符不是上下文关键字”来“面向未来”设计。

顺便说一句,这正是any标识符以@为前缀是合法的原因。

更多信息在这里:

http://ericlippert.com/2009/05/11/reserved-and-contextual-keywords/

【讨论】:

【参考方案3】:

只是一些上下文,在 ReSharper 5 中有一个错误:

groups.Select(group => ...)

会变成这个

from group in groups ...

现在,group 是 LINQ 查询语法中的关键字,因此 R#5 的重构实际上破坏了代码。在 R#6 中,这显然是使用 @ 作为标识符修复的。

【讨论】:

谢谢!我一直很困惑为什么 resharper 只在我的 Group 变量前面添加 @ 。现在这对我来说很有意义!【参考方案4】:

at 符号 (@) 对名称进行转义。例如。如果你想使用if 作为变量名,你可以写

int @if;

if 单独是行不通的,因为if 是一个 c# 关键字。

t前面的@在这里没用。可能写这篇文章的人正在使用他的私有命名约定并用它来表示 lambda 参数。

(好吧,我明白了,是 Resharper,不是一个人,但它本来可以是)。

【讨论】:

【参考方案5】:

我只看到@ 在这一重构中使用:将 LINQ 转换为方法链。在这种情况下,ReSharper 正在创建许多 lambda 变量(可能是一个 数,具体取决于要转换的 lambda 表达式的复杂性)。

关于原因的一个猜测是,他们可能故意使用了一些丑陋的东西,希望你能用有意义的名字代替它们。 ReSharper 可以用来猜测一个有意义的名称的提示并不多,所以这取决于您。

【讨论】:

【参考方案6】:

在生成的东西前加上 @ 前缀也是其他生成器的常见行为。 我至少在 wsdl.exe 生成的 Web 服务代理中看到了它。 WSDL 将一个属性命名为 protected,而 wsdl.exe 生成了一个名为 @protected 的属性。所以与C#关键字protected没有冲突。 但我不知道为什么在你的情况下 t 是前缀。您的班级中是否有名为 t 的静态成员?

【讨论】:

以上是关于ReSharper 为 lambda 表达式中的变量名提供“@”前缀的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Resharper 大量缩进 lambda?

为啥 Resharper 将此标记为“访问修改后的闭包”?

告诉 Resharper 一个 lambda 参数不为空

如何让 ReSharper 停止在 cshtml 中展开我的 lambda?

为啥不能为 Java 中的 var 关键字分配 lambda 表达式?

Java中的Lambda表达式