我可以将C#函数标记为"此函数不枚举IEnumerable参数"吗?

srm*_*srm 13 c# resharper ienumerable

对于我们来说,同一个可枚举的多次枚举是一个性能问题,所以我们尝试在代码中踩踏这些警告.但是我们有一个泛型扩展函数用于抛出生成大量这些警告的空参数异常.它的签名如下:

public static void VerifyArgumentIsNotNull<T>(this T value, string valueName) where T : class
Run Code Online (Sandbox Code Playgroud)

它所做的只是检查null并抛出一个格式良好的本地化(对于当时正在播放的人类语言)异常.

当此函数用于IEnumerable参数时,它会使代码分析警告IEnumerable可能的多次迭代,因为分析器不知道该函数的作用.

我想在这个函数上添加一些标记,"是的,这会将可枚举作为输入,但它不会迭代它,因此不应被调用者视为可能的迭代." 有没有这样的标签?我在互联网上搜索无济于事.

Iga*_*nik 18

是的,你所要求的是非常可能的,但需要一点工作.ReSharper使用代码注释为其分析引擎添加提示,并更好地理解它必须使用的代码.我最近在JetBrains上录制了一个名为ReSharper Secrets的网络研讨会,在那里我将详细介绍Annotations以及如何使用它们.你应该看看它!

有一个注释属性,[NoEnumeration]它完全符合您的要求 - 指定IEnumerable不枚举给定的参数,但它不包含在默认的代码注释属性中,但是它在JetBrains.Annotations.dll程序集中定义.

所以在介绍之后,这就是你需要做的:

  1. (如果还没有),请转到ReSharper选项,然后转到代码检查→代码注释,然后按复制默认实现到剪贴板按钮
  2. 在任何(共享)项目中创建一个文件Annotations.cs(或任何其他名称)
  3. 粘贴剪贴板中的代码,完全替换以前的任何内容 Annotations.cs
  4. 在文件末尾添加以下定义:

码:

/// <summary>
/// Indicates that IEnumarable, passed as parameter, is not enumerated.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class NoEnumerationAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

完成此操作后,剩下要做的就是将[NoEnumeration]属性放在value参数上,如下所示:

public static void VerifyArgumentIsNotNull<T>([NoEnumeration] this T value, string valueName) where T : class
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

就是这样!警告将消失!

奖金:

有3个可以用来装点这个方法,使之更加有用的附加属性:[NotNull],[ContractAnnotation][InvokerParameterName].我最近在这个问题中描述了他们做了什么(以及一个简短的演示),用于类似的名为LiteGuard的API.

注释很有趣:)