【问题标题】:C# shortcut for a List property that should never return null永远不应返回 null 的 List 属性的 C# 快捷方式
【发布时间】:2017-01-03 13:38:07
【问题描述】:

为了确保列表属性永远不会返回 null,我这样声明:

    private IList<Item> _myList;

    [NotNull]
    public IList<Item> MyList
    {
        get { return _myList ?? new List<Item>(); }
        set { _myList = value; }
    }

这行得通,但我讨厌这种语法。考虑到我应该在整个项目中广泛使用这种技术,我正在寻找一种更好的方法来编写这个或更好地解决同一问题。有什么想法吗?

【问题讨论】:

  • private readonly IList&lt;Item&gt; _myList = new List&lt;Item&gt;() 这将确保它永远不会为空
  • 如果我错了,请纠正我,但是即使你将_myList初始化为一个新的List,这并不意味着它的值以后不能设置为null。
  • @tocqueville true,只能在类的构造函数中设置。

标签: c# accessor


【解决方案1】:

这是一个很好的方法,但每次MyList 是必需的并且_myList 为空时,您将创建一个新的空列表...所以如果_myList 为空并且有人这样做MyList.Add(item); 它会不会被添加到正确的列表中。

最好这样做:

private IList<Item> _myList;

[NotNull]
public IList<Item> MyList
{
    get { return _myList ?? (_myList = new List<Item>()); }
    set { _myList = value; }
}

这样,第一次_myList 为空时,您将创建一个新列表。那么_myList 就不会为空了。

【讨论】:

  • 当支持成员是null 时,关于调用.Add() 的好处。 OP 的代码在这方面有一个重大错误,因为使用代码不会知道正在使用的列表会立即被丢弃。所有关于“这将表现不同”的其他答案的讨论似乎都忽略了当前行为已被破坏。
  • @tocqueville,是的,抱歉,已修复,我忘记了新列表周围的 ()。
  • 我测试了它并且它有效。关于 .Add() 问题的观点非常好,我没有想到这一点。谢谢。
  • C# 8 引入了复合赋值运算符 (??=) 使其更清晰:``` private IList _myList; [NotNull] public IList MyList { get => _myList ??= new List();设置 => _myList = 值; } ```
【解决方案2】:

从 C# 6.0 开始,您可以初始化使用自动实现字段的属性。这将确保 MyList 永远不会是空值:

public IList<Item> MyList { get; set; } = new List<Item>();

【讨论】:

  • 见 cmets on Zohar Peled 的回答,这和我的代码很不一样
【解决方案3】:

这行得通,但我讨厌这种语法。

我讨厌返回一个新列表并立即删除它是个好主意。我认为您应该尝试考虑其他方法来解决此问题。

返回的值真的不能为空吗?如果是这样,请创建一个适当的实例,而不是在创建它的那一刻将其删除:

[NotNull]
public IList<Item> MyList
{
    get { return _myList ?? (_myList = new List<Item>()); }
    set { _myList = value; }
}

如果您可以使用可空列表,您可能只想简写空检查:

if (list?.Contains(...) ?? false)
{ }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多