Multiple enumeration of the same enumerable is something that has been a performance problem for us, so we try to stomp those warnings in the code. But there is a generic extension function that we have for throwing null parameter exceptions that generates a lot of these warnings. Its signature looks like this:
public static void VerifyArgumentIsNotNull<T>(this T value, string valueName) where T : class
All it does is check for null and throw a nicely formatted and localized (for whichever human language is in play at the time) exception.
When this function is used on an IEnumerable parameter, it makes the code analysis warn about a possible multiple iteration of the IEnumerable because the analyzer has no idea what that function does.
I would like to put some tag on this function that says, "Yes, this takes the enumerable as an input, but it does not iterate it and therefore should not be counted as a possible iteration by callers." Is there any such tag? I've searched the Internet to no avail.
Yes, what you're asking is very much possible, but requires a little work. ReSharper uses Code Annotations to add hints to its analysis engine and make more sense of the code it has to work with. I recently recorded a webinar with JetBrains called ReSharper Secrets, where I go into much greater detail about what Annotations are and how to use them. You should watch it!
There's an annotation attribute, [NoEnumeration]
that does exactly what you ask - specifies that the given IEnumerable
argument is not enumerated, however it's not included in the default Code Annotation Attributes, however it is defined in the JetBrains.Annotations.dll
assembly.
So after this introduction, here's what you need to do:
Annotations.cs
(or any other name)Annotations.cs
Code:
/// <summary>
/// Indicates that IEnumarable, passed as parameter, is not enumerated.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class NoEnumerationAttribute : Attribute
{
}
After you done this, all that's left to do is place the [NoEnumeration]
attribute on the value
argument, like this:
public static void VerifyArgumentIsNotNull<T>([NoEnumeration] this T value, string valueName) where T : class
{
....
}
And that's it! The warning will disappear!
Bonus:
There are 3 additional attributes you can use to decorate this method to make it even more useful: [NotNull]
, [ContractAnnotation]
and [InvokerParameterName]
. I recently describe what they do (and a short demo) in this issue for a similar API called LiteGuard.
Annotations are fun :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With