Follow me
Latest replies
Categories
« Const vs. readonly vs. static readonly in C# .NET | Main | How to ensure that complex methods are covered with tests »
Thursday
23Oct

How to improve .NET code by integrating hints for ReSharper

As you already know, ReSharper provides a lot of helpful hints and suggestions for your .NET code.

Additionally, it has features, that allow it to help you leverage your own code. You just need to add a couple of annotations. Consider the example below.

Using Resharper hints in Lokad shared Library

As you can see, Resharper has detected that one of the arguments should actually be a string with the name matching "stream" and suggested to fix that.

This "feature" is implemented by decorating Enforce.ArgumentNotNull method with the InvokerParameterNameAttribute:

[DebuggerNonUserCode]
public static TValue ArgumentNotNull<TValue>(TValue value,
  [InvokerParameterName] 
  string argumentName) where TValue : class
{
  if (value == null)
  {
    throw new ArgumentNullException(argumentName);
  }
  return value;
}

In order to get InvokerParameterName (and the other attributes) into your code, you can either reference JetBrains.Annotations or copy and paste them into your code:

How to retrieve JetBrains.Annotations

Alternatively you can reference Lokad.Shared library that has these annotations, as well as many useful helper methods decorated with them for your convenience.

Here's the list of annotations currently supported by JetBrains ReSharper:

  • StringFormatMethod - method or ctor has format string argument
  • InvokerParameterName - the argument should be string literal that matches one of the parameters of the caller function
  • AssertionMethod - marked method could halt execution flow, if the condition is satisfied
  • TerminatesProgram - marked method terminates the program
  • CanBeNull - value of the marked element could be null sometimes, so check for null is needed (bad practice)
  • NotNull - value of the marked element could never be null
  • CannotApplyEqualityOperator- instance of the marked class (or its inheritors) can not be compared via the == or != (null checks are allowed)
  • BaseTypeRequired - decorated attribute can be applied only to the classes that have the specified base.

PS: I expect R# 4.5 to have way more features that improve coding experience. Till that happens, there still are R# Live Templates to explore.

Reader Comments (6)

Thank you for posting this! Just yesterday I was thinking about replacing my standard argument checking with something similar to your "Enforce.XYZ" example. However, I didn't, specifically because I could not live without ReSharper re-factoring support (I am assuming that if you rename stream R# will automatically update "stream"?).

November 15, 2008 | Unregistered CommenterBen Taylor

Ben,

yes, exactly. Additionally, you can set up the R# live template like this:

Enforce.ArgumentNotNull($Argument$, "$Argument$")
Where $Argument$ == suggest parameter name of type System.Object.

I've bound this template to "eann" and typing in null checks is like a breeze right now.

November 15, 2008 | Registered CommenterRinat Abdullin

Good tip. The only problem I have, is that after writing the method signature, I tend to use the Alt+Enter and then "Check argument for null" which auto-inserts the argument check and Exception throw. This is just slightly more convenient than using a Live Template and re-typing the argument name. Is it possible to extend the Alt+Enter menu? I am not next to my R# box, but I will try this out when I get home.

November 15, 2008 | Unregistered CommenterBen Taylor

Well, in case of this live template, you do not have to type in the argument name - all arguments are already displayed in the auto-completion drop-down dialog.

Re Alt+Enter extensibility: R# might support this through the plug-in system, but I've not looked at this system, yet.

November 15, 2008 | Registered CommenterRinat Abdullin

Hi Rinat, came across your blog and read down here :)

Cool stuff, keep it going!

I happen to be interested in R# annotations almost at the same time as you, and just wanna mention that it's possible to make annotations via XML as well as via C# attributes. With a library you can’t modify, XML is the only option.

March 6, 2009 | Unregistered CommenterAndrew

Hi Andrew,

Yes, I'm aware about the external XML annotations, but never had time to actually implement them against some library.

BTW, there are some quite interesting code analysis features in R# 4.5. Have you checked them out already?

March 10, 2009 | Registered CommenterRinat Abdullin

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>