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.

The null-coalescing operator in c# allows you to shorten the code

  if (_mywidget == null)
     return new Widget();
  else
     return _mywidget;

Down to:

  return _mywidget ?? new Widget();

I keep finding that a useful operator I'd like to have in C# would be one that allowed you to return a property of an object, or some other value if the object is null. So I'd like to replace

  if (_mywidget == null)
     return 5;
  else
     return _mywidget.Length;

With:

  return _mywidget.Length ??! 5;

I can't help thinking that there must be some reason for this operator not to exist. Is it a code smell? Is there some better way to write this? (I'm aware of the null object pattern but it seems overkill to use it to replace these four lines of code.)

share|improve this question
1  
Would the conditional operator suffice here? –  Anon. Jan 26 '11 at 0:28
    
In Clojure you can build a macro which does whatever. –  Job Jan 26 '11 at 1:31
1  
Someone has written something which enables you to do something like this: string location = employee.office.address.location ?? "Unknown";. This wil set location to "Unknown" when one of the object (either employee, office, address or location) is null. Unfortunately, I don't remember who wrote it or where he posted it. If I find it again, I will post it here! –  Kristof Claes Jan 26 '11 at 8:19
1  
This question would get much more traction on StackOverflow. –  Job Jan 26 '11 at 16:38
2  
??! is an operator in C++. :-) –  James McNellis Jan 26 '11 at 16:59
show 1 more comment

10 Answers 10

up vote 3 down vote accepted

I very much want a C# language feature that lets me safely do x.Prop.SomeOtherProp.ThirdProp without having to check each of those for null. In one codebase where I had to do those sorts of "deep property traversals" a lot, I wrote an extension method called Navigate that swallowed NullReferenceExceptions and instead returned a default value. So I could do something like this:

var propVal = myThing.Navigate(x => x.PropOne.PropTwo.PropThree.PropFour, defaultValue);

The downside of this is that it has a different code smell: swallowed exceptions. If you wanted to do something like this "right", you could take the lamdba as an expression, and modify the expression on the fly to add the null checks around each property accessor. I went for "quick and dirty" and didn't implement it this "better" way. But maybe when I have some spare thought cycles I'll revisit this and post it somewhere.

To more directly answer your question, I'm guessing the reason this isn't a feature is because the cost of implementing the feature exceeds the benefit from having the feature. The C# team has to pick and choose which features to focus on, and this one hasn't floated to the top yet. Just a guess though I don't have any insider info.

share|improve this answer
1  
Exactly what I thought, but the performance of the safe way would be quite bad I guess (because of the many Expression.Compile())... Too bad it's not implemented in C# (something like Obj.?PropA.?Prop1) –  Guillaume86 Jul 7 '11 at 11:01
    
x.PropOne.PropTwo.PropThree.PropFour is a poor design choice as it violates the Law of Demeter. Redesign your methods / classes so that you don't need to use this. –  Justin Shield Jul 13 '11 at 4:20
    
Mindlessly eschewing deep property access in light of the Law of Demeter is as dangerous as mindlessly normalizing a database. You can go too far. –  Mir Feb 21 at 0:39
add comment

It's really only speculation as to why they didn't do it. After all, I don't believe ?? was in the first C# version.

Anyways, I would just use the conditional operator and call it a day:

return (_mywidget != null) ? _mywidget.Length : 5;

The ?? is just a shortcut to the conditional operator.

share|improve this answer
4  
Personally, this is just as bad (imho) as having an operator to do this in the first place. You want something from an object... that object might not be there... so let's provide 5 as the answer in case it isn't there. You need to be looking at your design before you start asking for special operators. –  Moo-Juice Jan 26 '11 at 1:05
1  
@Moo-Juice I'm just imagining the person maintaining this code, 'Why is this giving me 5? Hrmmm. What?!' –  msarchet Jan 26 '11 at 16:16
add comment

It looks just like the ternary operator:

return (_mywidget != NULL) ? _mywidget : new Widget();
share|improve this answer
add comment

Personally, I think it is down to readability. In the first example, the ?? translates quite nicely as "Are you there?? Nope, let's do this".

In the second example, ??! is clearly WTF and means nothing to the programmer.... the object doesn't exist, so I can't get at the property so I'll return 5. What does that even mean? What is 5? How do we come to the conclusion that 5 is a good value?

In short, the first example makes sense... not there, new it. In the second, it's open to debate.

share|improve this answer
2  
Well, you have to ignore the fact that ??! doesnt exist. Imagine if ??! was common, and if it was used, then make decisions based on that. –  whatsisname Jan 26 '11 at 0:41
3  
That reminds me of the so-called "WTF operator" in C++ (this actually works: (foo() != ERROR)??!??! cerr << "Error occurred" << endl;. ) –  Tamás Szelei Jan 26 '11 at 0:41
    
@whatsisname, it was more a reflection on the fact that it was appropriate for the decision being made. To create an object because it wasn't there makes sense. To assign an arbituary value that means nothing to the reader because you can't get at a property of something, is indeed a WTF scenario. –  Moo-Juice Jan 26 '11 at 1:03
    
I think you're getting caught up in my example. Maybe 0 is better than 5. Maybe the property is an object so if _mywidget is null, you want to return a new foodle(). I completely disagree that ?? is more readable than ??! though :) –  Ben Fulton Jan 26 '11 at 4:06
    
@Ben, Although I agree that focusing on the operator itself doesn't lend too much to your question, I twas drawing a parallel to the perception of the programmer and that arbitrary 5. I really think there is more of an issue that you have to do something like this, whereas in your first example, the need is quite obvious, especially in things such as cache managers. –  Moo-Juice Jan 26 '11 at 8:10
show 2 more comments

I think people are getting too caught up in the "5" that you're returning... perhaps 0 would have been better :)

Anyway, I think the problem is that the ??! is not actually a standalone operator. Consider what would this mean:

var s = myString ??! "";

In that case, it makes no sense: it only makes sense if the left-hand operand is a property accessor. Or what about this:

var s = Foo(myWidget.Length) ??! 0;

There's a property accessor in there, but I still don't think it makes sense (if myWidget is null, does that mean we don't call Foo() at all?), or is this just an error?

I think the problem is it just doesn't fit as naturally in the language as ?? does.

share|improve this answer
add comment

Someone had created a utility class that would do this for you. But I can't find it. What I did find was something similar on the MSDN Forums (look at the second answer).

With a little work, you can extend it to evaluate method calls and other expressions that the sample doesn't support. You could also extend it to accept a default value.

share|improve this answer
add comment

I understand where you are coming from. It seems as if everyone is getting wrapped around the axel with the example you provided. While I agree that magic numbers are a bad idea, there would be use for the equivalent of a null coallescing operator for certain properties.

For example, you have objects bound to a map, and you want them to be at the proper elevation. DTED maps can have holes in their data so it is possible to have a null value, as well as values in the range of something like -100 to ~8900 meters. You might want something along the lines of:

mapObject.Altitude = mapObject.Coordinates.DtedAltitude ?? DEFAULT_ALTITUDE;

The null coallescing operator in this case would populate the default altitude if the Coordinates were not set yet, or the Coordinates object could not load DTED data for that location.

I see this as very valuable, but my speculation as to why it wasn't done is limited to compiler complexity. There may be some cases where the behavior would not be as predictable.

share|improve this answer
add comment

Magic numbers are usually a bad smell. If the 5 is an arbitrary number, then it's better to spell it out so that it's documented more clearly. An exception in my opinion would be if you have a collection of values which are acting as default values in a particular context.

If you have a set of default values for an object, you could subclass it to create a default singleton instance.

Something like: return (myobj ?? default_obj).Length

share|improve this answer
add comment

Length property usually is a value type so it can not be null, so the null-coalescing operator does not make sense here.

But you can do that with a property that is a reference type, for instance: var window = App.Current.MainWindow ?? new Window();

share|improve this answer
    
The example is trying to consider what would happen in your situation if Current was null. Your example would just crash... but having an operator that can null coalesce anywhere in the misdirection chain would be handy. –  Mir Feb 21 at 0:42
add comment

I have saw someone with a similar idea before but most of the time you'd want to also assign the new value into the null field, something like:

return _obj ?? (_obj = new Class());

so the idea was to combine the ?? and = assignment into:

return _obj ??= new Class();

I think this makes more sense than using an exclamation mark.

This idea is not mine but I really like it :)

share|improve this answer
1  
Are you a victim of the poor example? Your example can be shortened to return _obj ?? new Class(); there is no need for the ??= here. –  Matt Ellen Jan 26 '11 at 8:36
    
@Matt Ellen you got it wrong. The assignment is intended. I'm suggesting a different alternative. It's not quite exactly like what the OP asked for, but I believe it'll be just as useful. –  chakrit Jan 26 '11 at 9:52
1  
why do you want the assignment if you're about to return a value? –  Matt Ellen Jan 26 '11 at 9:58
    
lazy-initialization? –  chakrit Feb 7 '11 at 23:41
add comment

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.