24

I know the title of the question is very subjective, but I was confronted with usage of ?? operator by my peers, where at the same time I was not very happy/comfortable with applying var in new up-coming code.

The argument given for using ?? operator was, it takes away readability in code.

My question is, doesn't the same thing happens when you start using var?

Numan
  • 381

7 Answers7

53

Null coalescing operator (??)

Personally, I don't see any downsides to using this operator. Consider the following three code samples, from 'easy' to 'complex' new operators.

Without magic:

bool isNameSet = false;
string name;
if ( isNameSet )
{
    Console.WriteLine( name );
}
else
{
    Console.WriteLine( "No name set." );
}

Ternary operator:

bool isNameSet = false;
string name;
Console.WriteLine( isNameSet ? name : "No name set." );

Null coalescing:

string name = null;
Console.WriteLine( name ?? "No name set." );

The reason these operators were invented is because they represent very common programming operations. Not wanting to use them because you aren't used to them is just being stubborn. Languages evolve, features evolve, learn to use them!

var keyword

I have a somewhat different opinion about the var keyword. The type of a variable often gives extra information about your code. I find hiding the type by using the var keyword sometimes makes code less readable. You know less what to expect without using auto completion, or hovering over the identifiers to see what they actually are. In my opinion, this results in code which is slower to read/write.

I do use the keyword when I find that the type doesn't give much extra information.

  • Mainly in foreach loops, which I learned from Resharper as it is a setting there. Most of the time, you know what type of collection you are traversing, so you know you are expecting items from within that collection.
  • Linq queries. The result of linq queries are often very complex generic types. Displaying this type does more harm than good.
  • Long typenames which are simply initialized with their constructor. You can already tell what the type is by looking at the constructor.

As an example for the last statement:

ThisIsSomeSpecializedTypeRightHere duplication =
    new ThisIsSomeSpecializedTypeRightHere();
var justAsReadable =
    new ThisIsSomeSpecializedTypeRightHere();  // Less duplication.

// But I still prefer the following ...
int number = 9;
SomeCreatedType foo = Factory.CreateSomeType();
16

var allows less verbose code, which increases readability. In my opinion, readability should not be measured by how many details you see, but how many details are hidden at the first glance. Besides Linq examples, var allows duck typing at source code level, given the following example:

...
foreach (var message in messages) {
  var label = Factory.CreateLabel();
  label.Text = message;
  Controls.Add(label);
}
...

Who cares what is the type of label as long as it provide the Text property?

Codism
  • 1,213
16

I don't have any serious comments on the ?? operator, as I've never used a language with such an operator heavily. Regarding var, people program in languages like Ruby, Python, Perl and PHP that have fully implicit typing all the time. Natives of these languages realize that the formal type of a variable is usually irrelevant noise. You're more interested in what the variable can do, i.e. its structural/duck interface.

Similarly, I program mostly in D. D is statically typed but has the auto keyword, which is equivalent to var. It's considered idiomatic to use it everywhere unless you see a specific need to emphasize the type of something to either the reader or (via implicit conversion) the compiler. Except occasionally when used as a function return type (this is allowed in D), I've never found it to hamper readability, because I mostly think in terms of structural/duck interfaces, not formal/nominative types, when I program.

Furthermore, IMHO using var everywhere possible is a good example of DRY. The type of something should be specified in one and only one place, and then automatically be propagated whenever it needs to be propagated. If you use var and the formal type of the variable needs to change at some point, the necessary changes will automatically be propagated everywhere necessary by the compiler as long as the program is still type-correct, rather than the programmer having to manually change every instance. This is a Good Thing (TM).

dsimcha
  • 17,284
14

I think this is a question for the team in the end. If it's not readable to anyone else on my team then I won't use it, although I might try a couple of times to convince them with examples, or by pointing out analagous abbreviations (such as +=) which they find more readable.

However, if working alone then I find ?? and var emminently readable with no limits. Even

var a = b ?? c ?? d ?? e ?? "";

is pretty unambiguous to me.

Ternary operators and dynamic are a different matter, of course.

pdr
  • 53,768
10

The argument given for using ?? operator was, it takes away readability in code.

Briefly thinking about it, this comment tells me the person making the comment, doesn't understand it as well as he/she should. It is most likely true in certain situations, but on the whole, I don't discount something that the C# team obviously thought was important enough to add because of "readability". I put this in the same category of if(boolean_object) vs if(boolean_object == true). Some people argue that the second is more readable, but in reality it's just adding extra code for someone to read/type, and in some situations can be more confusing (think if(boolean_object != false))

My question is, doesn't the same thing happens when you start using var?

The C# team has allowed you to not define something which you know what it is going to be. Unless I absolutely need to define what a variable is going to be (either it is absolutely important that a returning object is of type x, or it really isn't readable), I use var. var x = "MY_STRING"; I know it's a string from looking at it. In truth, I don't really care that it's a string as long as it does what I need it to do. Defining the variable type is for my benefit, not the compiler's. If something is wrong, the compiler will tell me when it runs if I have the wrong variable type.

kemiller2002
  • 2,705
0

I have a fundamental issue with using var.

In this example everything is side-by-side, but the issue is really with large solutions with shared libraries or projects.

Consider this:

public MyFirstObject GetMeAnObject() {
    return new MyFirstObject();
}

public void MainProgram() {
    var theObject = GetMeAnObject();
    theObject.PerformOperation();
}

What happens if GetMeAnObject is changed, by someone else, to suit their needs?

public MySecondObject GetMeAnObject() {
    return new MySecondObject();
}

The MainProgram method will have a big red error on .PerformOperation(). What happened? PerformOperation worked perfectly well before. We look at the methods on theObject and it's just disappeared without a trace. It was there last time, and we need that method. You could spend a long time chasing your tail and trying to figure out why, if MyFirstObject has a method called PerformOperation, it now can't be seen. Everybody "knows" that GetMeAnObject returns a MyFirstObject, so there's no point checking that.

If you had explicitly typed theObject then you would have an Invalid Cast error on the line that calls GetMeAnObject, and it would be blindingly obvious that GetMeAnObject is returning a type that is not what you expect.

In short, explicit declaration means you know what the errors mean. An invalid cast means you expected one type and another type was returned. An unrecognised member means the member was unrecognised.

0

The var keyword is, in my opinion, bested used in the situations for which it was original introduced--LINQ queries. In these queries, the type of the returned result often has some big convoluted name that is difficult to determine ahead of time and doesn't aid the reader's understanding of what your code does.

However, doing var text = "Some text " + variableName + "some more text." is just lazy.

EDIT: @Jorg You jumped on a purposefully simplistic answer but added nothing to the discussion. OK, how about this for a better example: var items = doc.DocumentElement.FirstChild.ChildNodes; If you can figure out the type from that I'll give you a cookie.

Josh Earl
  • 553