97

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ます。

これは、nullの合体とはほぼ逆で、簡潔なインラインnullチェックと混ざり合っているように見えますが、C#にはそのような演算子がないことはほぼ確実です。

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

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

4

12 に答える 12

66

Groovyにはnullセーフな間接参照演算子(?。)があります...それがあなたが求めているものだと思います。

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

例えば:

homePostcode = person?.homeAddress?.postcode

personperson.homeAddressまたはがnullの場合、これはnullになりperson.homeAddress.postcodeます。

(これはC#6.0で利用できるようになりましたが、以前のバージョンでは利用できません)

于 2010-05-28T14:25:51.300 に答える
38

更新:要求された機能がC#6.0に追加されました。以下の2010年の元の回答は、歴史的な関心のみを考慮したものです。


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

于 2010-05-29T04:19:26.670 に答える
17

特別な種類の短絡ブール論理がある場合は、これを行うことができます (javascript の例):

return x && x.y;

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

于 2010-05-28T14:33:44.583 に答える
7

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

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

しかし、私はそれを見たくないというわけではありません!

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

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

于 2010-05-28T14:36:01.123 に答える
6

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

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

それまでの間、かゆみを掻き立てるような IfNotNull()があります。確かに?より大きいです。または:、しかし、メンバーの1つがnullの場合にNullReferenceExceptionを発生させない一連の操作を構成できます。

于 2010-05-28T14:33:28.473 に答える
3

>>Haskellでは、次の演算子を使用できます。

  • Nothing >> NothingNothing
  • Nothing >> Just 1Nothing
  • Just 2 >> NothingNothing
  • Just 2 >> Just 1Just 1
于 2010-05-28T14:50:25.700 に答える
3

Haskell にはfmapがあり、この場合は と同等だと思いますData.Maybe.map。Haskell は純粋に関数型なので、探しているものは

fmap select_y x

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

于 2010-05-28T15:23:24.793 に答える
2

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);
于 2010-05-28T14:41:17.397 に答える
2
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"
于 2013-03-12T23:23:53.807 に答える
1

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

例えば:

z = new Thingy { y=null };

次に、あなたの代わりに

return x != null ? x.y : null;

あなたは書ける

return (x ?? z).y;
于 2012-01-04T19:20:09.870 に答える
1

これは、C# vNext (Roslyn を利用した C#、Visual Studio 2014 でのリリース) に追加されています。

これは Null 伝播と呼ばれ、完全なものとしてここにリストされています。 https://roslyn.codeplex.com/wikipage?title=言語%20機能%20ステータス

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

于 2014-11-30T22:11:53.613 に答える