2

With in the introduction of anonymous types in C# we got the var keyword.

Now people use var everywhere instead of the correct type. The reasons I've heard given for this are:

  • It makes refactoring easier
  • It's shorter
  • it improves readability

A common example might be

var result = client.GetResult(query);

is better than:

MyObject result = client.GetResult(query);

Because if you refactor GetResult to return a different object; for example:

MyOtherObject result = client.GetResult(query);

you don't have to also refactor the calling code.

However I recently had to do the following refactoring

IEnumerable<MyObject> GetResult(query)

to

Task<List<MyObject>> GetResult(query)

The calling code was along the lines of

//return true if there are any results
var result = client.GetResult(query);
if(result != null)
{
    return true;
}
return false;

Which after the refactoring would still compile and always return true. Whereas the explicitly typed form would have thrown a compilation error.

So. The question is. Given that there are downsides to using var instead of the explicitly typed variable. Is it simply a case of coding style preference, or are there clear reasons to use, or not use var in this fashion? (ie. other than where required with anonymous types)

12
  • 2
    i think i would try to think about the project priorities. Are you making medical or military equipment? Dealing with highly private or sensitive information? If so, explicit typing can help with protection. If I'm making a survey site for coworkers only, then spending little time is more important.
    – DaFi4
    Aug 22, 2016 at 8:32
  • 7
    Your example, IMO, is not one of the refactoring cases. You are changing the way that method behaves (from sync to async), which completely changes the signature of the method. You're right that not using var here would help a little bit in detecting the error when changing method signature. However, for such a change, I'll always review all references anyway.
    – Harry Ninh
    Aug 22, 2016 at 9:01
  • 1
    I'd go further than @HarryNinh and say that if you are changing the return type from IEnumerable<MyObject> to Task<List<MyObject>> then you are completely changing what the method does and so should have changed the method name too. Renaming from GetResult to GetResultTask would have instantly then picked up all the places where the calling code needed changing.
    – David Arno
    Aug 22, 2016 at 10:14
  • 2
    Regarding your question, the use of var is very much a style thing. Some (like myself) use it everywhere. Others hate it so much they even define a type called var to try and block it's use. It's a subjective thing. Finding objective reasons for either approach is hard.
    – David Arno
    Aug 22, 2016 at 10:39
  • 4
    But you wouldn't want to use the "rename refactor" in this case as you'd want to rewrite all the calling code. I feel your example is invalid as using such an auto-refactor would be a bad thing to do in this case. From experience, those that use var a lot, also tend to use a more declarative programming approach, avoid mutability, write shorter methods and classes, write unit tests (which would have failed after your Task change) etc. It's part of a mindset. Looking at var in isolation therefore misses the point to a certain extent.
    – David Arno
    Aug 22, 2016 at 11:32

2 Answers 2

9

FWIW I do find that var is overused. That doesn't mean it shouldn't be used though. These are the standards we use at my workplace.

  1. Use var when the type is obvious.

    var foo = new Foo();
    
  2. Don't use var when the return type isn't obvious.

    Foo foo = service.GetItem();
    
  3. Don't use var when the method returns a concrete type.

    ICollection<Foo> items = new List<Foo>();
    
8
  • 3
    The problem with this answer is that it's pure opinion. Sure, in your workplace, these rules apply. So what? In other workplaces, other rules apply. It therefore isn't a useful answer.
    – David Arno
    Aug 22, 2016 at 13:33
  • @DavidArno I didn't have a ton of time to justify these here, but I will later. It's maybe pure opinion as written, but there are objective arguments for all of this.
    – RubberDuck
    Aug 22, 2016 at 13:35
  • I very much doubt it, but I'm happy to be proven wrong. In the meantime, the upvotes show that some people at least agree with your opinions.
    – David Arno
    Aug 22, 2016 at 14:31
  • 3
    @DavidArno: I've been doing C# for awhile now, and these are precisely the guidelines I use. I use them because they make sense. Aug 22, 2016 at 14:54
  • 3
    @RobertHarvey, Clearly they are a popular set of guidelines. 2 and 3 make no sense to me though. I guess it depends whether one is a "I've used C# for a while" person, or a "I've used C# and F# for a while". For me, F#'s "infer everything" approach makes sense, so I'd use var in all three cases. Though I'd probably never write example (3) as it's likely to be followed by a bunch of Add() calls, which don't fit the approach I take to coding and I wouldn't have a method return a concrete type, if it could return an interface implementation.
    – David Arno
    Aug 22, 2016 at 15:02
2

As already stated , use of var is totally optional (other than declaring anonymous type). It is only a coding style preference.

I would use explicit type declaration when assigning value from a function. But it is only for the readability, not for the advantage if and when the calling function would be refactored.

The quoted example is indeed bad. Usually we'd perform an operation on the returned object. If there were some operations performed on the returned object from client.GetResult, definitely there would be a compilation error.

We don't normally return true or false after checking null. The called function can very well return true / false itself.
Or, as the return value before refactoring was IEnumerable<MyObject> the function client.GetResult could have returned an empty list (Null object pattern?) instead of null....just saying..

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.