One Annotations Way, Resharper

September 21, 2008 21:33

     

 


Do you remember that final episode from the fourth season of a great movie "Lost", where Jack, Desmond, Kate with Claire's infant baby, Sawyer, Sayid, Hurley and Frank Lapidus were in a helicopter on their way back to the island? All of a sudden, Ben moved the island to another place.

Jeez. It was a disaster: tranquil waterscape at the very place of a firm land.

In software development, we call this NullReferenceException. Lash of all developers, the high price we pay for not initializing variables and using null as a "sign of unassigned".



How to mitigate this?

A lucky user of Resharper, I'll be talking from that perspective. External annotations framework introduced in 4.0 allows us to benefit from its code analysis. JetBrains guys did a great job annotating system libraries so that you'd get a warning like this one:

      


And we can reuse the same technique for our own libraries (to dispel apprehensions: yes, I’ve created a sample project for download[1]). Two options are available
. You can either apply annotations attributes directly in the code:

 

public static int GetLength([NotNull] string text)
{
     return text.Length;
}


Or, aternatively, make annotations via XML:

<member name="M:Bar.GetLength(System.String)">
  <parameter name="text">
     <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
  </parameter>
</member>


Then, if you’re using the method with a potentially null string, Resharper will scream bloody murder (depends on your settings though):

 


If the codebase is frequently changing, having attributes directly in the code is probably better than annotating via XML. Good news for those odd guys who’d better abstain from having JetBrains.Annotations namespace scattered all over:

  1.       ReSharper | Options | Code Annotations

  2.       Copy default implementation to clipboard and paste it under your namespace

  3.       Update default annotations namespace, restart VS and enjoy


On the other hand, for a library you can’t modify, XML is the only option. In this case, a file [library-name].ExternalAnnotations.xml should be put side by side with the dll itself, and in order to see the result you’d need to restart Visual Studio. Note that XML annotations work only with dll files, so you have to make sure you reference a library as a dll, not as a project in a solution.


Anything besides NotNull?

Currently Resharper provides 9 annotation attributes located in JetBrains.Annotations.dll. My favorite ones:

    ·         NotNull

    ·         CanBeNull

    ·         TerminatesProgram

    ·         CannotApplyEqualityOperator

Perhaps, NotNull and CanBeNull are still most useful. People may argue that the language itself needs a special not-null indicator (like exclamation mark in Spec#), but that’s another day question. Well above 60% of all references end up being not-null anyway, so a lot of code would be mottled with exclamations. Are we ready for this? Maybe yes – at least, it’s less verbose than using attributes. A more elegant solution that will never come true is to apply value type syntax for reference types: all references are implicitly not nulls for the compiler, but a question mark after a type (ie: «string?» or «Customer?») allows you to set null to the variable.

 


Footnotes:

[1] – A sample project with External Annotations of Resharper (7 Kb).
 

 


Comments are closed