繁体   English   中英

用法?? 运算符(null-coalescing operator)

[英]Usage of ?? operator (null-coalescing operator)

我用 ?? 我的代码非常重视运算符。 但今天我刚遇到一个问题。

这里我用的代码是什么? 操作者

private List<string> _names;
public List<string> Names
{
    get { return _names ?? (_names = new List<string>()); }
}

但在某些地方我也看过这个代码。

private List<string> _names;
public List<string> Names
{
    get { return _names ?? new List<string>(); }
}

这些代码之间的真正区别是什么。 在一个我分配_names = new List()而在其他我正在做新的List()。

我看到的唯一区别是,在第一种情况下,您的变量_names将包含一个新的空列表,而在第二种情况下它不包含。 在这两种情况下,返回的值都是相同的。

在第二种情况下你没有为_names分配new List<string>() ,如果_names null,每次调用Names它都会创建new List<string>() ,但在第一种情况下, new List<string>()创建一个。

它将在两种情况下返回相同的值,但不同之处在于,如果您在私有函数中的任何位置访问_names,则_names在第一种情况下将具有空列表,但在第二种情况下将为空值。 因此,根据编码标准,第一个实现是正确的,在第二种情况下,您可能会面临null异常的问题。

正如其他人所说,区别在于检索属性后字段_names的状态。

情况1

get { return _names ?? (_names = new List<string>()); }

如果_names为null,则将创建并分配新的List<string> 在此之后,每次检索属性Names都将返回刚刚创建的列表。

案例2

get { return _names ?? new List<string>(); }

如果_names为null,则返回新的List<string> 与案例1相比,它不会被分配给任何东西。 这意味着每次检索Names ,都会创建并返回一个新列表。


话虽这么说,你应该非常小心这个代码的两个版本。 get中分配值不一定是好事。 懒惰地实例化属性值很方便,并且在你是唯一一个使用该类的情况下可能是可以接受的,但它的风格很差。 类外的用户不指望一个get设置什么...这就是该set物业的一部分是。 从长远来看,你最好只返回_names并在默认构造函数中实例化它。 然后很清楚代码在做什么,并且您获得了保证的非null属性值。

对于第二种情况,你是好得多返回null并允许用户来处理它。 考虑以下情况,其中items是一个大型对象集合,每个对象都包含您的属性Names ,无论出于何种原因, Names始终为null:

foreach (var item in items.Where(x => x.Names != null)) {
    Console.WriteLine(String.Join(", ", item.Names));
}

如果您只是返回null,则会跳过整个块。 但是,由于每次都返回一个新列表,不仅是你在整个循环中运行而且基本上什么也没做,你在每次迭代时都要实例化一个新列表! 在某些条件下,这可能会非常昂贵。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM