web-dev-qa-db-ja.com

null合体演算子の「反対」はありますか? (…任意の言語で?)

nullの合体はおおよそ_return x, unless it is null, in which case return y_に変換されます

私はしばしば_return null if x is null, otherwise return x.y_を必要とします

_return x == null ? null : x.y;_を使用できます

悪くはありませんが、真ん中のnullはいつも私を悩ませます-それは不必要に思えます。 _return x :: x.y;_のようなものが好まれます。この場合、_::_に続くものがnullではない場合にのみ評価されます。

私はこれをほぼヌル合体の反対であり、簡潔でインラインのヌルチェックと混合されているように見えますが、私は[ほぼ]がないことを確信していますC#のそのような演算子。

そのような演算子を持つ他の言語はありますか?もしそうなら、それは何と呼ばれますか?

(C#でメソッドを記述できることは知っています。return NullOrValue.of(x, () => x.y);を使用しますが、もっと良いものがあれば、それも見たいと思います。)

91
Jay

null-safe逆参照演算子(?。)がGroovyにあります...それはあなたが望んでいることだと思います。

(これは 安全なナビゲーション演算子 とも呼ばれます。)

例えば:

homePostcode = person?.homeAddress?.postcode

personperson.homeAddressまたはperson.homeAddress.postcode 無効です。

(これは現在 C#6.0で使用可能 ですが、以前のバージョンでは使用できません)

62
Jon Skeet

?を追加することを検討しました。 C#4へ。それはカットをしませんでした。これは「持っている」機能であり、「持っている」機能ではありません。将来のバージョンの言語については、この点について再度検討しますが、私があなただったら、私は息を止めません。時間が経つにつれ、それ以上重要になることはないでしょう。 :-)

36
Eric Lippert

特別な種類の短絡ブールロジックがある場合は、これを実行できます(JavaScriptの例)。

return x && x.y;

xがnullの場合、x.yは評価されません。

16
Eric

これを答えとして追加するのは正しいと感じました。

C#にそのようなものが存在しない理由は、合体演算子(参照型に対してのみ有効)とは異なり、逆の演算は参照型または値型(つまり、メンバーclass xを含むint y)を生成する可能性があるためです。残念ながら、多くの状況で使用できなくなります。

しかし、私はそれを見たくないと言っているのではありません!

その問題の潜在的な解決策は、演算子が右側の値型式を自動的にnullableに持ち上げることです。しかし、その場合、yがintであるx.yが実際にint?を返すという問題があります。

別の、おそらくより良い解決策は、左側の式がnullの場合、演算子が右側の型のデフォルト値(つまりnullまたは0)を返すことです。しかし、その場合、ゼロ/ヌルが実際にx.yから読み取られたシナリオ、またはそれがセーフアクセスオペレーターによって提供されたかどうかを区別する問題が発生します。

7
Andras Zoltan

Delphiには(。ではなく):演算子があり、これはnullセーフです。

彼らは?を追加することを考えていました。演算子をC#4.0に変換して同じことを行いますが、チョッピングブロックを取得しました。

当面は、IfNotNull() かゆみを掻くようなものがあります。確かに?または:でも、メンバーの1つがnullの場合にNullReferenceExceptionを発生させない一連の操作を作成できます。

6
48klocs

Haskellにはfmapがあり、この場合は_Data.Maybe.map_と同等だと思います。 Haskellは純粋に機能するので、探しているのは

_fmap select_y x
_

xNothingの場合、Nothingを返します。 xが_Just object_の場合、Just (select_y object)を返します。ドット表記ほどきれいではありませんが、関数型言語であることから、スタイルは異なります。

3
Norman Ramsey

Haskellでは、>>演算子:

  • Nothing >> NothingNothingです
  • Nothing >> Just 1Nothingです
  • Just 2 >> NothingNothingです
  • Just 2 >> Just 1Just 1
3
dave4420

PowerShellを使用すると、null参照でプロパティを参照できます(メソッドを呼び出すことはできません)。インスタンスがnullの場合、nullを返します。これはどの深さでも実行できます。 C#4の動的機能がこれをサポートすることを期待していましたが、サポートしていません。

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

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

それはきれいではありませんが、あなたが記述する方法で機能する拡張メソッドを追加することができます。

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);
2
Josh
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; }
}

私はよくこのロジックを文字列に必要とします:

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"
2
J Bryan Price

メンバーのすべての正しいデフォルト値を使用して、クラスの静的インスタンスをどこかに作成します。

例えば:

_z = new Thingy { y=null };_

あなたの代わりに

_return x != null ? x.y : null;_

あなたは書ける

return (x ?? z).y;
1
Nick

いわゆる「null条件演算子」は、C#6.0とVisual Basic 14で導入されました。
多くの状況で、ヌル結合演算子の正反対として使用できます。

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

1
Jpsy

これはC#vNext(Roslyn搭載C#、Visual Studio 2014と共にリリース)で追加されています。

これはヌル伝播と呼ばれ、完全なものとしてここにリストされています。 https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status

また、完全なものとしてここにリストされています: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c

1
Micah Zoltu