保护foreach循环不为空的更智能的方法
本文关键字:智能 方法 foreach 循环 保护 | 更新日期: 2023-09-27 18:03:52
是否有一种更聪明的方法来保护foreach
循环免受NullReference异常的影响:
if (G_Locatie.OverdrachtFormulierList != null)
{
foreach (OverdrachtFormulier otherform in G_Locatie.OverdrachtFormulierList)
{
...
}
}
我使用了很多foreach循环,通常是嵌套的,还有很多变量,比如G_Location确实存在,但是datammember . overdrachtformulierlist可能还没有被分配一个list use 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;
}
有趣的是c#似乎可以保护你免受许多错误的影响。如果您不取消Sandbox()
中的初始化注释,则此代码将无法构建,因此第一个foreach
将不会获得NullReferenceException
。
但是,您最好取消注释MyComplexClass
中的init,以避免第二个foreach
中的异常。c#可以在有或没有这个初始化的情况下构建。
所以在我的实际代码中,我只需要在G_Locatie的Class定义中添加一个简单的初始化。
现在唯一的问题是,我一直想用{get; set;}
简化上面的代码,但这是不可能的初始化描述。我将不得不忍受那个小问题。
实际上,对于对象类型属性,并不需要setter。
最后,我意识到我找不到一个合适的题目来描述我的问题。到目前为止,我遇到的每一个问题都已经在这个论坛上得到了解答,我觉得我今天不得不发帖只是因为我找不到类似的帖子。也许有人能想出标题和标签,使这个解决方案更容易找到。是的,你的集合属性应该返回空集合而不是null。确保这一点的一种方法是使用一个后备字段,并在getter中分配一个新列表:
private List<string> overdrachtFormulierList;
public List<string> OverdrachtFormulierList
{
get
{
return this.overdrachtFormulierList ??
(this.overdrachtFormulierList = new List<string>());
}
set
{
this.overdrachtFormulierList = value;
}
}
您也可以使用Enumerable.Empty<T>
,如果您的类型是IEnumerable<T>
一个选择是创建一个扩展方法:
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable source)
{
return source ?? Enumerable.Empty<T>();
}
:
foreach (var otherform in G_Locatie.OverdrachtFormulierList.EmptyIfNull())
{
...
}
请注意,始终使用空集合比使用空引用更可取。