如何编写以下场景的简写?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
如何编写以下场景的简写?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
使用空合并运算符( ?? ):
get
{
_rows = _rows ?? new List<Row>();
return _rows;
}
或(可读性较差):
get { return _rows ?? (_rows = new List<Row>()); }
这 ??运算符称为空合并运算符。如果操作数不为空,则返回左侧操作数;否则返回右手操作数。
这是惰性初始化模式,因此直接的方法是使用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。
我建议三元运算符
get {
return _rows == null ? _rows = new List<Row>() : _rows;
}
或者由于空List<Row>
不会带来太多开销,为什么不摆脱显式_row
字段并仅实现只读属性(C# 6.0语法):
public IList<Row> Rows {get;} = new List<Row>();
这是一个更好的主意:防止_rows
永远存在null
。
让你的构造函数初始化变量:
public MyClass()
{
this._rows = new List<Row>();
}
然后你的财产只是
get
{
return this._rows;
}
确保如果您需要“清除”变量,您总是调用它的Clear
方法或分配一个新的空列表而不是分配null
. 如果您确实需要在整个课程中使其清晰和一致,则可以在方法中对该操作进行编码。
这更符合逻辑。如果你的变量永远不应该null
,它永远不应该null
。它还巧妙地避免了条件和 getter 修改状态的问题。
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());
像这样的例子:
get{ return _rows ?? (_rows = new List<Row>()); }
如果您希望您的代码表现得像您当前的代码一样,在访问属性时延迟初始化您的支持字段,那么是的,您可以缩短它。您可以重命名您的支持字段,因为已回答已用于??
将所有内容放在单个表达式中,并且当您拥有该单个表达式时,请使用 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},而无需每次都再次输入。
return _rows ?? (_rows = new List<Row>());
您可以通过以下任何一种方式执行此操作:
- 条件运算符 (?:)
- 空合并运算符 ( ?? )
使用条件运算符
get {
return _rows == null ? new List<Row>() : _rows;
}
空合并运算符
get {
return _rows ?? new List<Row>();
}
如果你真的想缩短它,我会删除额外的括号。
get
{
if (_rows == null)
_rows = new List<Row>();
return _rows;
}