1

I just read Shortest way to check for null and assign another value if not, but a question remains.

Consider this commonly seen code pattern:

if ( !string.IsNullOrEmpty(source) )
    dest = source;

It's possible to express it as a one-liner using the null-coalescing operator:

dest = source ?? dest;

[Edit:] Thanks @Rango for realising these are not equivalent. But the following sure is:

dest = !string.IsNullOrEmpty(source) ? source : dest;

However, one would guess this alternative is not strictly equivalent to the former (although the observable result is). I say "guess" in this context because I'm not sure of whether the IL bytecode would be identical or not.

In either case, are there any shorter ways of not assigning anything, not even the original value, to the variable dest in the case where source is null? Even if a trick using a bitwise operator or something more clever. I was actually hoping for a syntax similar to the null-conditional operator.

Thanks.

Marc.2377
  • 7,807
  • 7
  • 51
  • 95
  • 5
    How could it be the same? The former checks also if it's an empty string – Tim Schmelter Feb 08 '19 at 17:29
  • @Rango damn, that is correct. I just came up with this over-simplified example based on existing logic and totally overlooked this fact. – Marc.2377 Feb 08 '19 at 17:31
  • The equivalence will also depend on whether `source` is a field or a local variable. – Jon Skeet Feb 08 '19 at 17:31
  • 1
    _"using a bitwise operator"_ you prefer that over a readable `if`? – Tim Schmelter Feb 08 '19 at 17:33
  • Theoretically you could create a normalizing function and use it. Something like `dest = MyNormalizeString(source) ?? dest;` This function returns null for invalid strings. But the question remains - why do you want to achieve this ? The solution with `if` operator is more readable with less code. – Fabjan Feb 08 '19 at 17:35
  • @Rango No. But i'm curious. – Marc.2377 Feb 08 '19 at 17:36
  • @JonSkeet Can you point me some reference about it? btw, I'm buying C# In Depth this weekend. Been on my list for a while now. – Marc.2377 Feb 08 '19 at 17:48
  • 3
    Possible duplicate of [Is there a case for a String.IsNullOrEmpty operator?](https://stackoverflow.com/questions/3406694/is-there-a-case-for-a-string-isnullorempty-operator) – Kami Feb 08 '19 at 17:51
  • 1
    @Marc.2377: It's not in terms of IL, but the effect. `source ?? dest` will only read `source` once. The first version doesn't. Imagine if `source` is non-null and non-empty in the first read, but then becomes null in another thread before the second read (and if that read is actually performed - memory models are hard), `dest` will end up being null. – Jon Skeet Feb 08 '19 at 17:53
  • @JonSkeet Right. But how does this behavior vary based on whether it is a field or a local variable? (edit) I'm guessing the answer is, local vars cannot be accessed from another thread? – Marc.2377 Feb 08 '19 at 18:00
  • 1
    Precisely that. Reading a local variable like that twice will (almost always) give you the same result both times. (`ref` parameters would change that, but...) – Jon Skeet Feb 08 '19 at 18:19

1 Answers1

2

I've been using C# for a long time, and as far as I know, the answer is no.

The two options you have are:

1.) Using an if check to short-circuit the logic and skip it if it's not necessary. This should be the fastest to execute, on average.

2.) Using the ternary operator to check and assign in one line. Depending on the intermediate compiler, this could be a tiny bit slower, but it should be the shortest code possible to achieve this effect (at least that's readable).

Ultimately, the problem boils down to Strings effectively being immutable arrays. Assignments are as fast as assigning an integer if the String is already in memory (as it would be since you're referencing existing variables), but checking null and empty is at least two checks (the null check and the length check) which can't be avoided to maintain the functionality. The extra assignment in the ternary is really the only variable for speed of execution (whereas the if version short-circuits that when null).

So, no matter what, you'll need to do the checks, and perform the assignment if necessary. I don't see any way to avoid that, ultimately, so it can't get any faster/shorter than these two use-cases.

Louis Ingenthron
  • 1,267
  • 8
  • 21