c# - Enumerable.Empty<T>() 是代替 foreach 循环中的 null 检查的好选择(C#)?

标签 c# .net linq

假设我们有类(class):

public class Notes
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Text { get; set; }
}

public class Configuration
{
    public List<Notes> ImportantNotes { get; set; }
}

然后,为了处理可能导致 ImportantNotes null 的情况,我们将执行以下操作:

if (config.ImportantNotes != null)
{
    foreach(var note in config.ImportantNotes)
    {
        ....
    }
}

到目前为止,我在代码中经常使用这种模式,但最近我开始了解 Linq 的 Enumerable.Empty() 方法。我可以这样使用:

foreach(var note in config.ImportantNotes ?? Enumerable.Empty<ImportantNotes>())
{
    ....
}

我已经检查过,它在实际代码中确实运行良好,但我不确定它是否好用。那么,使用它来处理空检查是否更好?如果不是那么为什么不呢?

最佳答案

当使用像List<T>这样的集合属性时您应该将您的类设计为仅管理一个无法替换的列表,或者使集合本身只读,但属性可设置。因此,考虑其中之一:

public class Configuration
{
    // Everyone can add or remove items, but the list itself can't be replaced.
    public List<Notes> ImportantNotes { get; } = new();
}

public class Configuration
{
    // Everyone can replace the list, but items can't be changed.
    // Assume only good citizens and don't check for anyone setting this to null.
    public IReadOnlyList<Notes> ImportantNotes { get; set; } = Array.Empty<Notes>();
}

public class Configuration
{
    private readonly List<Notes> _ImportantNotes = new();

    // Everyone can read this list, but the configuration only can add or remove items.
    public IReadOnlyList<Notes> ImportantNotes { get => _ImportantNotes }
}

public class Configuration
{
    private IReadOnlyList<Notes> _ImportantNotes = Array.Empty<Notes>();

    // Everyone can replace the list, but items can't be changed.
    // Assume also bad citizens and check for anyone setting this to null.
    public IReadOnlyList<Notes> ImportantNotes
    {
        get => _ImportantNotes;
        set => _ImportantNotes = value ?? throw new ArgumentNullException();
    }
}

请记住,所有这些方法都是有效的。没有更好或更坏。它们都有各自的优点和缺点,这取决于最适合您给定问题的用例。我始终遵循的唯一规则是集合永远不应该是 null 。它可以包含零个元素,但它本身永远不是 null 。后面应该是返回集合的属性和方法(集合是否是 List<T>IReadOnlyDictionary<TKey, TValue>IEnumerable<T>IReadOnlySet<T> 或任何其他类似类型或接口(interface)都没有关系)。

关于c# - Enumerable.Empty<T>() 是代替 foreach 循环中的 null 检查的好选择(C#)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75862595/

相关文章:

c# - 日期时间分钟格式 :00

c# - OnDeserialized 使用 xml 序列化

c# - .NET:HttpClient 使用我的接口(interface) IHttpClient 模拟它,但有一个内部对象为 NULL,它是密封的

c# - 如何改进我的算法以将数据存储在硬盘上?

c# - 我如何在 Linq 中分组?

xml - LINQ to XML 查询属性

c# - 如何使用 Linq 选择单条记录?

.net - WinForms 中的水印文本框

c# - LINQ 中的 GroupBy 与字符串 [] 数组

C# HttpListener : IE11 does not apply CSS