62

如何编写以下场景的简写?

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

    return _rows;
}
4

11 回答 11

81

使用空合并运算符( ?? ):

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

或(可读性较差):

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

这 ??运算符称为空合并运算符。如果操作数不为空,则返回左侧操作数;否则返回右手操作数。

于 2016-07-08T12:37:58.370 回答
41

这是惰性初始化模式,因此直接的方法是使用Lazy<T>类。

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

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

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

这具有额外的优点,即它不会用初始化逻辑“污染”getter。

于 2016-07-08T17:06:58.010 回答
20

我建议三元运算符

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

或者由于空List<Row>不会带来太多开销,为什么不摆脱显式_row字段并仅实现只读属性(C# 6.0语法):

public IList<Row> Rows {get;} = new List<Row>();
于 2016-07-08T12:39:30.313 回答
18

这是一个更好的主意:防止_rows永远存在null

让你的构造函数初始化变量:

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

然后你的财产只是

get
{
    return this._rows;
}

确保如果您需要“清除”变量,您总是调用它的Clear方法或分配一个新的空列表而不是分配null. 如果您确实需要在整个课程中使其清晰和一致,则可以在方法中对该操作进行编码。

符合逻辑。如果你的变量永远不应该null它永远不应该null。它还巧妙地避免了条件和 getter 修改状态的问题。

于 2016-07-08T21:20:03.500 回答
12
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());
于 2016-07-08T12:44:04.050 回答
10

正如其他人所说,您可以在这种情况下使用空合并运算符。

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

值得注意的是,这是ReSharper非常擅长建议的一种更改(他们称之为快速修复)。

在您的示例中,它将在if语句下方放置一个小波浪线。将鼠标悬停在它上面会显示有关如何更改/简化代码的建议。

转换成 '??'  表达

几次点击后,更改就实施了。

在此处输入图像描述

于 2016-07-08T15:01:44.907 回答
5

像这样的例子:

get{ return _rows ?? (_rows = new List<Row>()); }
于 2016-07-08T12:42:40.360 回答
3

如果您希望您的代码表现得像您当前的代码一样,在访问属性时延迟初始化您的支持字段,那么是的,您可以缩短它。您可以重命名您的支持字段,因为已回答已用于??将所有内容放在单个表达式中,并且当您拥有该单个表达式时,请使用 C# 6 的新属性语法来避免编写getreturn

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},而无需每次都再次输入。

于 2016-07-09T18:14:35.193 回答
1
return _rows ?? (_rows = new List<Row>());
于 2016-07-08T12:37:40.137 回答
0

您可以通过以下任何一种方式执行此操作:

  • 条件运算符 (?:)
  • 空合并运算符 ( ?? )

使用条件运算符

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

空合并运算符

get { 
  return _rows ?? new List<Row>(); 
}
于 2016-07-30T00:50:20.387 回答
0

如果你真的想缩短它,我会删除额外的括号。

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

        return _rows;
    }
于 2016-07-08T12:46:32.343 回答