18

Do the null-conditional operator and interpolated strings syntax resolve to just syntactic sugar?

The null-conditional operator (?.), which allows code clean-up through reducing "excessive" null checking, and interpolated strings (("\{X}, \{Y}")), which brings the arguments and format into one, are new features in C# 6.

Do these get compiled to their undesirable counterparts (i.e. the ugly code we sought to avoid)?

I apologize for the naïve question, I don't have the best understanding of languages in general, but I'm curious if it would be possible to run these features on, say, C# 5.

I know this is the case with Java in some instances, is it true as well with these examples?

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
ChiefTwoPencils
  • 13,548
  • 8
  • 49
  • 75
  • 2
    Elvis operator is something else. It's actually a **Null coalescing operator**, which picks the first non-null value. `?.` is trying to traverse the object down the property chain, it returns non-null only if the whole chain evaluation succeeded. http://en.wikipedia.org/wiki/Null_coalescing_operator UPDATE - found a name for `?.`, it's called [Safe Navigation Operator](http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx). – Victor Zakharov Dec 15 '14 at 21:38
  • C# already has the [`??` operator](http://msdn.microsoft.com/en-us/library/ms173224.aspx). Is that not the same thing? – Ryan Bemrose Dec 15 '14 at 21:40
  • [Apparently not](http://channel9.msdn.com/Events/Visual-Studio/Connect-event-2014/116). @RyanBemrose. Maybe it is but is changed`??` – ChiefTwoPencils Dec 15 '14 at 21:40
  • 4
    As an update to future readers, the "Elvis operator" has been officially named the "null-conditional operator" in C# 6.0 – Nick Orlando Jan 16 '15 at 17:42
  • 6
    I like Elvis operator better :) – Randall Deetz Nov 05 '15 at 19:28
  • 1
    Who cares what your code is compiled into? The only considerations you should have are 1) what is the most concise and clear way I can express an algorithm and 2) how fast and reliable is the result of the compilation. You realize that GOTO is used extensively in IL, right? ***GOTO***. Imagine all your clean, elegant code reduced to a bunch of lousy GOTO statements. Now go shower. –  Jun 30 '16 at 14:46

3 Answers3

31

There isn't a general rule, it differs. Some features are simply syntactic sugar, some add capabilities that weren't possible before, and some are a combination of both.

Syntactic Sugar

  • String interpolation - This:

    string result = $"{bar}";
    

    Instead of:

    string result = string.Format("{0}", bar);
    
  • Null-propagating operator (?.) - This:

    var result = Foo()?.Length
    

    Instead of:

    var temp = Foo();
    var result = (temp != null) ? temp.Length : null;
    

New Capabilities

  • String interpolation - Also adds support for IFormattable using FormattedString so this is possible:

    IFormattable result =  $"{bar}"
    
  • Await in catch/finally - It's now possible to use await in catch and finally blocks:

    try
    {
    }
    catch
    {
        await Task.Delay(1000);
    }
    

There are of course more features in both categories, like exception filters and expression-bodied members.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • So maybe the general rule for programmers is to either have a thorough understanding of the behaviors of these features or default to the version they're implemented. – ChiefTwoPencils Dec 15 '14 at 21:47
  • @ChiefTwoPencils that's reasonable. – i3arnon Dec 15 '14 at 21:55
  • So, I apparently have been writing C# from a very basic level. Why is `?.` needed if we already have `??` as suggested in the comments? Are they redundant or changed? – ChiefTwoPencils Dec 15 '14 at 22:01
  • 2
    @ChiefTwoPencils those are different operators with different purpose. `??` is the null coalescing operator. `?.` is the null conditional operator (or safe navigation operator) – i3arnon Dec 15 '14 at 22:04
  • 4
    1. `var result = GetString() ?? string.Empty;` 2. `var result = GetString()?.Length` – i3arnon Dec 15 '14 at 22:06
  • 1
    @PauloMorgado of course. That's why it was already available in IL. – i3arnon Dec 16 '14 at 12:45
11

Like most of the new features in C#6.0, the null-conditional operator is just shorthand (syntactic sugar, if you want to call it) for a pattern of getting the value of a member if the instance the variable being used is not null.

Given a s of type string, this:

int? l = s?.Length;

is translated into:

int? l = s == null ? null : s.Length;

And it can be combined with the null coalescing operator (??):

int l = s?.Length ?? 0;

String interpolation also started as shorthand for string.Format but evolved to a pattern that can either produce a string or an IFormatble. Please, refer to the current spec for more information.

And, by the way, roslyn is the code name for the compiler platform, not the languages or their features.

Nick Orlando
  • 484
  • 1
  • 5
  • 17
Paulo Morgado
  • 14,111
  • 3
  • 31
  • 59
  • Yes, roslyn is the name for the compiler platform. I asked about the code these features were compiled to, someone edited the post and added the tag, seemed appropriate/reasonable to me. A distinction/clarification between your claims and the accepted answer would be great. Thanks for the link; I currently don't have the time to do spec reading hence asking here, but will dive in soon. – ChiefTwoPencils Dec 16 '14 at 16:46
  • 1
    @ChiefTwoPencils, the link I posted is for the spec of the string interpolation - fairly short. As for the "Elvis" operator, unless you want to spend a month or two going through all the discussions, it's pretty much what I posted. – Paulo Morgado Dec 16 '14 at 19:54
2

The Elvis operator is very useful when calling the RaisePropertyChanged event.

In the past you would write

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs(nameof(X));
}

But there was a potential multi threading issue if PropertyChanged was set to null before it was invoked. Instead you can write:

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(X));

Which completely avoids the multi threading issue - so it's not quite Syntax sugar.

Peter
  • 29
  • 1
  • 1
    minor note: "in the past" `nameof()` did not exist. it entered the language together with the null-conditional operator. also, the race condition was resolved by extracting both references to a local variable. so you "only" save a few keystrokes (which is not necessarily something to be scoffed at) – sara Feb 24 '16 at 11:27
  • 1
    even smaller note: Null-propagating operator is the `?.` which you are referring to above as the Elvis operator which is the `?:` which does indeed look like Elvis. – ericosg Apr 12 '16 at 16:05
  • 1
    No, it does *not* avoid multi threading issues, they are just shifted slightly. See http://stackoverflow.com/a/35786442/1671066. – Micha Wiedenmann Nov 08 '16 at 10:01
  • @MichaWiedenmann, MSDN: https://msdn.microsoft.com/en-us/library/dn986595.aspx says otherwise. – astrowalker Apr 11 '17 at 07:40