Resharper – Going too var?

Since installing Resharper 5.1, about a year ago, I’ve found it to be an invaluable tool.  One of its more controversial tenets is that all variables should be implicitly typed, not strongly typed, ie:

string rockStatus = “Iain rocks the casbah!”;

Should be

var rockStatus = “Iain implicitly rocks the casbah!”;

The rationale for this is held to be two-fold:

  1. It makes your code more readable, ie:
    1. Dictionary<int, object> example = new Dictionary<int, object>(); is a pain to write and read, much better to just use var
  2. It encourages developers to give their variables a more meaningful name, since the type is not present to impart additional meaning.
Aside – Personally I think another reason is it makes C# a bit more like the dynamic languages that all the cool kids are running (hello Ruby).  “Dude, thinking about what types my variables will hold, gets in the way of discovering the conceptual model of what I’m building.  There is no spoon, maaaaan”

Having resisted the notion for a while, I came round to this way of thinking (re points 1 and 2, not about the spoon ;-)), and generally I think Resharper is correct.

However, refactoring some code today, I realised there are a couple of potential pitfalls, one that could be very common in Web programming with MVC, and a less common scenario.

1. Using an implicitly typed variable for variables that are set from an external method, and then returned to a view.

ie:

public ActionResult Index()
{
    var model = _activityStreamService.GetActivityStream("iain");
    return View(model);
}

Now if you, as I did, refactored the external method to return a different type.  The compiler doesn’t help you as your var is implicitly typed to the new return type, and the first you know about it is when the view blows up.  On a complex system this may go unnoticed for a while.

2. Using an implicitly typed variable that are set from an external method, and downcasted when being processed by another method.

ie (imagine Helpers is a different class, I just put them together for quickness),

public string ToJson(object serializeMe)
{
    var jSerializer = new JavaScriptSerializer();
    return jSerializer.Serialize(serializeMe);
}

public ActionResult Index()
{
    var activityStream = _activityStreamService.GetActivityStream("iain");
    var json = Helpers.ToJson(activityStream);

    return View(json);
}

In this example if we refactor the return type from activityStreamService you may be in even more serious trouble, you might completely miss that there’s a problem until your customers complain.

The counter arguments to this are that UnitTests would hopefully catch this scenario (although interestingly if you’re using implicit variables in your unit tests, they might not, plus who honestly has 100% coverage).  Also return types are rarely refactored, you might change the body of the method, but if it started off returning a string it probably always will.

But I think the more important point is that there are cases where using implicit typing is a bad choice, and may store up trouble for you, especially in large projects.

Advertisements

One thought on “Resharper – Going too var?

  1. While I agree with you about your second example as the JSON will cause that to slip by unnoticed, if you’re using strongly typed views your first scenario is far less likely. I’ve found that following Resharper’s advice is good about 99% of the time. I’ve even run into a scenario where ignoring the “access to modified closure” warning actually did produce a problem! Like any other rule though, it’s best to follow them until you discover when to break the rules. By the time you reach that point, you should be prepared to weigh the risks correctly. 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s