9

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.)

8
  • 1
    Would the conditional operator suffice here?
    – Anon.
    Commented Jan 26, 2011 at 0:28
  • 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! Commented Jan 26, 2011 at 8:19
  • 1
    This question would get much more traction on StackOverflow.
    – Job
    Commented Jan 26, 2011 at 16:38
  • 2
    ??! is an operator in C++. :-) Commented Jan 26, 2011 at 16:59
  • 3
    Hello 2011, just called to say that c# is getting a safe navigation operator
    – Nathan
    Commented Aug 11, 2014 at 10:22

12 Answers 12

5

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.

4
  • 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) Commented Jul 7, 2011 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. Commented Jul 13, 2011 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
    Commented Feb 21, 2014 at 0:39
  • 3
    In C# 6.0 this is possible by using the Null-Conditional Operator (a.k.a. the Elvis operator) msdn.microsoft.com/en-us/magazine/dn802602.aspx Commented Dec 5, 2014 at 0:39
15

I believe you'll be able to do this with C# 6 quite simply now:

return _mywidget?.Length ?? 5;

Note the null-conditional operator ?. on the left side. _mywidget?.Length returns null if _mywidget is null.

A simple ternary operator might be easier to read, though, as others have suggested.

9

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.

2
  • 5
    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
    Commented Jan 26, 2011 at 1:05
  • 1
    @Moo-Juice I'm just imagining the person maintaining this code, 'Why is this giving me 5? Hrmmm. What?!'
    – msarchet
    Commented Jan 26, 2011 at 16:16
4

It looks just like the ternary operator:

return (_mywidget != NULL) ? _mywidget : new Widget();
3

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.

7
  • 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. Commented Jan 26, 2011 at 0:41
  • 3
    That reminds me of the so-called "WTF operator" in C++ (this actually works: (foo() != ERROR)??!??! cerr << "Error occurred" << endl;. ) Commented Jan 26, 2011 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
    Commented Jan 26, 2011 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
    Commented Jan 26, 2011 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
    Commented Jan 26, 2011 at 8:10
2

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.

1

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.

1

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.

1

When not dealing with deeply nested I've used this (before the null coalescing operator introduced in C# 6). For me it's pretty clear, but maybe that's because I'm used to it, other people might find it confusing.

return ( _mywidget ?? new MyWidget() {length = defaultLength}).Length;

Of course, this is not always applicable, since sometimes the property you need to access cannot be set directly, or when the construction of the object itself is expensive, amongst other reasons.

Another alternative is to use the NullObject pattern. You define a single static instance of the class with sensible default values, and use that instead.

return ( _mywidget ?? myWidget.NullInstance).Length;
0

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

0

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();

1
  • 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
    Commented Feb 21, 2014 at 0:42
-1

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 :)

4
  • 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
    Commented Jan 26, 2011 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
    Commented Jan 26, 2011 at 9:52
  • 2
    why do you want the assignment if you're about to return a value?
    – Matt Ellen
    Commented Jan 26, 2011 at 9:58
  • lazy-initialization?
    – chakrit
    Commented Feb 7, 2011 at 23:41

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