web-dev-qa-db-ja.com

nullの可能性がある値を返す簡単な方法はありますか?

次のシナリオの速記を書くにはどうすればよいですか?

get
{
    if (_rows == null)
    {
        _rows = new List<Row>();
    }

    return _rows;
}
61
ErrorAgain

null-coalescing operator (??)を使用:

get 
{ 
     _rows = _rows ?? new List<Row>(); 
     return _rows; 
}

または(読みにくい):

get { return _rows ?? (_rows = new List<Row>()); }

??演算子は、null合体演算子と呼ばれます。オペランドがnullでない場合、左側のオペランドを返します。それ以外の場合は、右側のオペランドを返します。

81
Zein Makki

これは遅延初期化パターンであるため、簡単な方法は Lazy <T> クラスを使用することです。

class Foo
{
    Lazy<List<Row>> _rows;

    public Foo()
    {
        _rows = new Lazy(() => new List<Row>());
    }

    public List<Row> Rows
    {
        get { return _rows.Value; }
    }
}

これには、初期化ロジックでゲッターを「汚染」しないという追加の利点があります。

41
Roman Reiner

三項演算子をお勧めします

get {
  return _rows == null ? _rows = new List<Row>() : _rows;
}

または空のList<Row>は、明示的な_rowフィールドと読み取り専用プロパティの実装(C#6.構文):

public IList<Row> Rows {get;} = new List<Row>();
20
Dmitry Bychenko

より良いアイデアを次に示します。Prevent _rowsこれまでからnull

コンストラクターに変数を初期化させます。

public MyClass()
{
    this._rows = new List<Row>();
}

そしてあなたの財産はただ

get
{
    return this._rows;
}

変数を「クリア」する必要がある場合は、必ずClearメソッドを呼び出すか、nullを割り当てる代わりに新しい空のリストを割り当ててください。クラス全体で明確で一貫性を保つ必要がある場合は、メソッドでその操作をエンコードすることもできます。

これはmuchより論理的です。変数がnullであってはならない場合、nullであってはなりません。また、条件の取得とゲッターの変更状態の問題の両方をきれいに回避します。

18
jpmc26
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());
12
Sinatr

他の人が言ったように、このシナリオではヌル合体演算子を使用できます。

get
{
    return _rows ?? (_rows = new List<Row>());
}

これは、 ReSharper が提案するのに優れている(彼らはそれを quick-fix と呼ぶ)種類の変更であることは注目に値します。

あなたの例では、ifステートメントの下に小さな波線を入れます。その上にカーソルを置くと、コードを変更/簡略化する方法を示す 提案 が表示されます。

Convert to '??' expression

数回クリックすると、変更が実装されます。

enter image description here

10
Richard Everett

たとえば次のように:

get{ return _rows ?? (_rows = new List<Row>()); }
5
eocron

コードを現在のコードのように動作させ、プロパティにアクセスしたときにバッキングフィールドを遅延初期化したい場合は、短くすることができます。回答済みのように、バッキングフィールドの名前を変更できます。すでに??すべてを単一の式に入れ、その単一の式がある場合は、C#6の新しいプロパティ構文を使用して、getおよびreturnを記述しないようにします。

List<Row>_;List<Row> Rows=>_??(_=new List<Row>());

願わくば、この点に到達するかなり前に、あなたが望んでいることを正確に理解するコードを、決して維持したくない恐ろしい混乱に変えたことがわかるでしょう。

コードをそのままにしてください。図のように短くすることもできますが、それでも改善されません。

同じコードを何度も入力し続けるため、書くのに時間がかかるという問題がある場合、多くのIDEには、テンプレート、スニペット、またはそれに使用する用語を挿入する機能があります。これにより、次の行に沿って何かを定義できます。

{Type} {Field};
public {Type} {Property} {
  get {
    if ({Field} == null) {
      {Field} = new {Type}();
    }
    return {Field};
  }
}

エディターは、特定の{Type}、{Field}、{Property}の入力を求めます。毎回入力する必要はありません。

3
user743382
return _rows ?? (_rows = new List<Row>());
1

これは、次のいずれかの方法で実行できます。

  • 条件演算子(?:)
  • ヌル結合演算子(??)

条件演算子を使用

get {
  return _rows == null ? new List<Row>() : _rows;
}

ヌル結合演算子

get { 
  return _rows ?? new List<Row>(); 
}
0
Abdul Moiz Khan

本当に短くしたい場合は、余分なブラケットを削除します。

    get
    {
        if (_rows == null)
            _rows = new List<Row>();

        return _rows;
    }
0
Tyler Nichols