Reputation: 4164
This is ReSharper 7 with Visual Studio 2012. With the sample below
// This code works fine and as expected and ReShrper is happy with it
if (!string.IsNullOrWhiteSpace(extension) && extension.Length == 3)
{
// do something
}
// ReSharper highlights "extension" in extension.Length with "Possible 'System.NullReferenceException'"
if (!extension.IsNullOrWhiteSpace() && extension.Length == 3)
{
// do something
}
And, I have created the following extension method:
public static class StringExtensions
{
public static bool IsNullOrWhiteSpace(this string s)
{
return string.IsNullOrWhiteSpace(s);
}
}
I looked at the reflected code of String.IsNullOrWhiteSpace
and it doesn't have any related code or attribute that would highlight to R# that the check is verified. Is this hardcoded in R#?
I looked at Code Contracts, but I am not sure it would help in my case.
Do you have a workaround for proving to ReSharper that the check condition is already verified by my extension method?
Upvotes: 10
Views: 2347
Reputation: 17719
[ContractAnnotation("null=>true")]
public static bool IsNullOrWhiteSpace(this string s)
Your project isn't going to know what ContractAnnotation
is. You need to add it to your project. The preferred method is via nuget:
PM> Install-Package JetBrains.Annotations
Alternatively you can directly embed the source into your project:
Resharper -> Options -> Code Annotations -> Copy default implementation to clipboard
Then paste that into a new file, eg Annotations.cs. The ContractAnnotation
definition lives in that file. For an official article on ContractAnnotation see here
Is this hardcoded in R#?
No, Resharper uses External Annotations to provide this functionality. This article should answer all your questions, including a solution to provide your own external annotation for your IsNullOrWhiteSpace
method.
note: external annotations appear to only work on referenced libraries; if your reference is from a project the external annotations are not picked up; this is less than ideal
Suppose you have your extension method in a class called TempExtensions
which itself resides in an assembly named ClassLibrary1
You need to add a new file at this location
C:\Program Files (x86)\JetBrains\ReSharper\v7.0\Bin\ExternalAnnotations.NETFramework.ExternalAnnotations\ClassLibrary1\ClassLibrary1.xml
The contents of the xml should contain:
<assembly name="ClassLibrary1">
<member name="M:ClassLibrary1.TempExtensions.IsNullOrWhiteSpace(System.String)">
<attribute ctor="M:JetBrains.Annotations.ContractAnnotationAttribute.#ctor(System.String,System.Boolean)">
<argument>null=>true</argument>
<argument>true</argument>
</attribute>
</member>
</assembly>
Upvotes: 16
Reputation: 1396
The only workaround I see is by adding function parameter to extension method.
public static class StringExtensions
{
public static bool IsNotNullAndNotWhiteSpaceAnd(this string s, Func<string, bool> func)
{
if (string.IsNullOrWhiteSpace(s))
{
return false;
}
return func(s);
}
}
Example for using this extension method:
string extension = null; //Test for null
//string extension = "123"; //Test for Length==3
if (extension.IsNotNullAndNotWhiteSpaceAnd(_ => _.Length == 3))
{
Console.Out.WriteLine("Length == 3");
}
else
{
Console.Out.WriteLine("Null or WhiteSpace or Length != 3");
}
Upvotes: 0
Reputation: 9384
As far as i know is this a problem of the resharper. It can not look into methods and verify that in the method the null-check will be done. If u want to avoid this message i think u have to do the null-checking yourself. But i would prefer to ignore the resharper-message in this situation.
Upvotes: 0