保护foreach循环免受null的更聪明的方法

Rol*_*and 1 c# foreach null

是否有一种更智能的方法来保护foreach循环免受NullReference异常的影响:

if (G_Locatie.OverdrachtFormulierList != null)
{
    foreach (OverdrachtFormulier otherform in G_Locatie.OverdrachtFormulierList)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用了很多foreach循环,经常嵌套,以及很多变量,例如G_Location肯定存在,但是datamember .OverdrachtFormulierList可能还没有被分配列表使用new.


亲爱的朋友们,感谢你们的所有评论.在了解了你的建议之后,虽然很难理解,但在深入了解Lasagna代码后,我开始研究,经过一些实验,我发现最简单最干净的方法是简单地避免使用NULL,正确初始化.虽然我有点不得不在我的代码中初始化OverdrachtFormulierList,但有遗忘一个实例的风险,我找到了适当的初始化位置,即在原始类定义中.

为简单起见,请查看以下代码:

    class MyClass
    {
        public List<string> items = new List<string>();

        public IEnumerator<string> GetEnumerator()
        {
            return items.GetEnumerator();
        }
    }

    class MyComplexClass
    {
        private MyClass _itemlist /*= new MyClass()*/;
        public MyClass itemlist
        {
            get { return _itemlist; }
            set { _itemlist = value; }
        }
    }

    void Sandbox()
    {
        MyClass mc /*= new MyClass()*/;
        foreach (string Sb in mc.items)
        {
            string x = Sb;
        }

        MyComplexClass mcc = new MyComplexClass();
        foreach (string Mb in mcc.itemlist) // <--- NullReferenceException
        {
            string x = Mb;
        }

        return;
    }
Run Code Online (Sandbox Code Playgroud)

有趣的是,C#似乎可以保护您免受许多错误的错误.如果您不取消注释初始化,则不会构建此代码Sandbox(),因此第一个foreach不会获得NullReferenceException.

但是,您最好取消注释init MyComplexClass以避免在第二个中出现异常foreach.C#将使用和不使用此初始化进行构建.

事实证明,在我的实际代码中,我只需要在G_Locatie的Class定义中添加一个简单的初始化.

现在唯一的问题是我一直想简化上面的代码,{get; set;}但是如上所述的初始化是不可能的.我将不得不忍受那个小问题.

实际上,在对象类型属性上,您并不真正需要setter.

最后,我意识到我找不到适合自己问题的标题.到目前为止,我所遇到的每一个问题都已在本论坛中得到解答,我觉得我今天只能发帖,因为我找不到与此类似的帖子.也许有人可以提出标题和标签,使这个解决方案更容易找到.

dev*_*tal 6

是的,您的集合属性应该返回空集合而不是null.确保这一点的一种方法是使用支持字段并在getter中分配新列表:

private List<string> overdrachtFormulierList;

public List<string> OverdrachtFormulierList 
{
     get
     {
        return this.overdrachtFormulierList ?? 
            (this.overdrachtFormulierList = new List<string>());
     }

     set
     {
        this.overdrachtFormulierList = value;
     }
}
Run Code Online (Sandbox Code Playgroud)

Enumerable.Empty<T>如果你的类型是你也可以使用IEnumerable<T>


Jon*_*eet 5

一种选择是创建扩展方法:

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable source)
{
    return source ?? Enumerable.Empty<T>();
}
Run Code Online (Sandbox Code Playgroud)

然后:

foreach (var otherform in G_Locatie.OverdrachtFormulierList.EmptyIfNull())
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,始终使用空集合而不是空引用仍然是优选的.