Is there an “opposite” to the null coalescing oper

2019-01-13 09:24发布

null coalescing translates roughly to return x, unless it is null, in which case return y

I often need return null if x is null, otherwise return x.y

I can use return x == null ? null : x.y;

Not bad, but that null in the middle always bothers me -- it seems superfluous. I'd prefer something like return x :: x.y;, where what follows the :: is evaluated only if what precedes it is not null.

I see this as almost an opposite to null coalescence, kind of mixed in with a terse, inline null-check, but I'm [almost] certain that there is no such operator in C#.

Are there other languages that have such an operator? If so, what is it called?

(I know that I can write a method for it in C#; I use return NullOrValue.of(x, () => x.y);, but if you have anything better, I'd like to see that too.)

12条回答
该账号已被封号
2楼-- · 2019-01-13 09:32

Delphi has the : (rather than .) operator, which is null-safe.

They were thinking about adding a ?. operator to C# 4.0 to do the same, but that got the chopping block.

In the meantime, there's IfNotNull() which sort of scratches that itch. It's certainly larger than ?. or :, but it does let you compose a chain of operations that won't hork a NullReferenceException at you if one of the members is null.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-13 09:33

If you've got a special kind of short-circuit boolean logic, you can do this (javascript example):

return x && x.y;

If x is null, then it won't evaluate x.y.

查看更多
▲ chillily
4楼-- · 2019-01-13 09:37

In Haskell, you can use the >> operator:

  • Nothing >> Nothing is Nothing
  • Nothing >> Just 1 is Nothing
  • Just 2 >> Nothing is Nothing
  • Just 2 >> Just 1 is Just 1
查看更多
仙女界的扛把子
5楼-- · 2019-01-13 09:37

PowerShell let's you reference properties (but not call methods) on a null reference and it will return null if the instance is null. You can do this at any depth. I had hoped that C# 4's dynamic feature would support this but it does not.

$x = $null
$result = $x.y  # $result is null

$x = New-Object PSObject
$x | Add-Member NoteProperty y 'test'
$result = $x.y  # $result is 'test'

It's not pretty but you could add an extension method that will function the way you describe.

public static TResult SafeGet<T, TResult>(this T obj, Func<T, TResult> selector) {
    if (obj == null) { return default(TResult); }
    else { return selector(obj); }
}

var myClass = new MyClass();
var result = myClass.SafeGet(x=>x.SomeProp);
查看更多
倾城 Initia
6楼-- · 2019-01-13 09:37
public class ok<T> {
    T s;
    public static implicit operator ok<T>(T s) { return new ok<T> { s = s }; }
    public static implicit operator T(ok<T> _) { return _.s; }

    public static bool operator true(ok<T> _) { return _.s != null; }
    public static bool operator false(ok<T> _) { return _.s == null; }
    public static ok<T> operator &(ok<T> x, ok<T> y) { return y; }
}

I often need this logic for strings:

using ok = ok<string>;

...

string bob = null;
string joe = "joe";

string name = (ok)bob && bob.ToUpper();   // name == null, no error thrown
string boss = (ok)joe && joe.ToUpper();   // boss == "JOE"
查看更多
Emotional °昔
7楼-- · 2019-01-13 09:41

The so called "null-conditional operator" has been introduced in C# 6.0 and in Visual Basic 14.
In many situations it can be used as the exact opposite of the null-coalescing operator:

int? length = customers?.Length; // null if customers is null   
Customer first = customers?[0];  // null if customers is null  
int? count = customers?[0]?.Orders?.Count();  // null if customers, the first customer, or Orders is null

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

查看更多
登录 后发表回答