Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question

migrated from codereview.stackexchange.com Mar 16 '11 at 14:00

This question came from our site for peer programmer code reviews.

38  
If a "developer" can't understand the ?? null coalesce operator after it's explained, they shouldn't be allowed near production code. –  CaffGeek Mar 16 '11 at 20:47
9  
I suggest we change the operator from ?? to IfNullThen. ? can be IfSoChoose, : is ElseChoose. + is Add. - is Subtract, unless it's unary, then it's Negative. -- is split between DecrementBeforeUsing, and DecrementAfterUsing. In C++ you can do this with macros. –  Lee Louviere Nov 9 '11 at 15:07
6  
@Xaade: That's irony isn't it? ... right? ... god let it be irony (and I'm an atheist). –  Steven Jeuris Nov 9 '11 at 21:21
10  
@StevenJeuris It might be sarcasm, but it's not irony. –  Kirk Broadhurst Nov 10 '11 at 2:51
1  
@KirkBroadhurst: I stand corrected, have always been confusing those two. –  Steven Jeuris Nov 10 '11 at 9:49

7 Answers 7

up vote 44 down vote accepted

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();
share|improve this answer
15  
That last example is exactly when the var keyword can excel. Imagine that code is littered throughout your code. Factory.CreateSomeType returns IEnumerable<SomeType>. One day, for whatever reason, it changes to return SomeType[]. If you've used var, it's just a recompile. –  pdr Mar 16 '11 at 13:06
1  
Got that example the wrong way around and then went to find food. Numpty! A better example would be using yours. What if Factory.CreateSomeType() changes to return an ISomeType? –  pdr Mar 16 '11 at 13:27
3  
@pdr: That most likely means the interface changed as well, and behavior needs to be adjusted/added as well. If it's a simple rename you ofcourse have automated renaming. If the 'contract' changes, I rather see my code breaking so I can see whether I have to adjust something or not. –  Steven Jeuris Mar 16 '11 at 13:36
2  
I think it's much more likely that if returning a concrete type becomes returning an interface that it is just allowing for other concrete types with the same interface (consistent with the Factory pattern). But if the contract does change then your code will break - though you may find it only breaks in a few cases where it matters rather than everywhere. –  pdr Mar 16 '11 at 13:46
1  
@Tom Hawtin, we all know it's inevitable to avoid null entirely. Furthermore, the more I look for alternatives for null, the more I realize using null is sometimes the cleanest solution. My given example isn't all that bad IMHO, and I find it an appropriate usage of nullable types. –  Steven Jeuris Mar 16 '11 at 14: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).

share|improve this answer

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.

share|improve this answer
4  
I would use `String.Empty' here. –  Job Mar 16 '11 at 20:04
1  
@Job, in honesty, so would I. I was going to put something in that string, then couldn't think of anything :) –  pdr Mar 16 '11 at 20:13
4  
var a = b ?? c ?? d ?? e ?? String.Empty ?? ""; –  Lee Louviere Nov 9 '11 at 15:09
2  
@Xaade You can never be sure enough. But really, using String.Empty or "" is a personal preference. I use "" because it's shorter... –  Carra Nov 10 '11 at 14:19
11  
@Xaade - if String.Empty ever returns null, we're in for one hell of a lot of broken code. –  Jesse C. Slicer Nov 10 '11 at 18:29

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?

share|improve this answer
    
Someone trying to understand whether this is e.g. a winforms label or a WPF label. –  Steven Jeuris Mar 16 '11 at 14:45
14  
@Steven Jeuris: that's usually a known context information. If not, you are approaching the code in a wrong way. –  Codism Mar 16 '11 at 14:58
    
Someone who wants to know whether it is a default WPF label or some custom label then? :) –  Steven Jeuris Nov 9 '11 at 21:24
12  
1. Should that person really care, so long as it's a label with a Text property? 2. If this is one of the rare cases that they REALLY DO have a good reason to care, ask Intellisense. 3. If they're editing code in an IDE without Intellisense, they probably have way bigger inconveniences than 'var' :) –  Michael Edenfield Nov 10 '11 at 20:12
3  
Someone with a poor sense of abstraction. –  Jim Balter May 10 '13 at 18:39

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.

share|improve this answer

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.

share|improve this answer
16  
If you can't figure out that "Some text " is a string, then you have much bigger problems to worry about than the number of vars in your code. –  Jörg W Mittag Mar 16 '11 at 16:26
2  
The problem isn't var; the problem is the crappy variable name "items". If you use a good variable name, there's nothing wrong with var. –  Kyralessa Nov 10 '11 at 18:30
1  
I'm guessing (without looking) that items is a collection of XML nodes, which I expect to have all of the properties and methods of a collection of XML nodes, and that's really all I need to know. –  Michael Edenfield Nov 10 '11 at 20:16
    
If you need to know what type the var stands for and can't tell immediately by looking, just hover the mouse over it. Doesn't take much figuring out to do it. –  scrwtp Dec 1 '11 at 1:11
    
@scrwtp I just tried hovering over items; it didn't show me anything... –  ratchet freak May 25 '12 at 9:35

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.

share|improve this answer
7  
A co-worker made a breaking change in code not covered by tests, and you think the problem is var? The language cannot be expected to protect against that sort of behaviour--what if they'd modified MyFirstObject directly? It would still have broken, but no syntax could have saved you from that. I'd consider this a strength of var, even: what if instead of returning MySecondObject you were now returning IMyFirstObject instead? –  Phoshi Aug 15 '12 at 11:31
1  
"Everybody "knows" that GetMeAnObject returns a MyFirstObject, so there's no point checking that." I can't actually think of a scenario in programming where I would actually depend on my memory of what GetMeAnObject if I am debugging. If I checked that PerformOperation is not there, I would have seen the code and no it is for another class. If in an IDE the class would pop up the instance I look at the type of the object. Actually, when the compiler tells me the error, it would say 'class MySecondObject has no operation PerformOperation'. How is that for everybody knows? –  Muhammad Alkarouri Aug 15 '12 at 13:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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