我有两个通过JSON反序列化填充的列表
List<MyType> a = JsonConvert.DeserializeObject<List<MyType>>(jsonstringa);
List<MyType> b = JsonConvert.DeserializeObject<List<MyType>>(jsonstringb);
然后,我对每一个进行迭代,并执行一些逻辑。这些藏品可能是空的,这是完全合理的。
foreach (MyType myA in a)
{
//DO STUFF HERE
}
foreach (MyType myB in b)
{
//DO STUFF HERE
}
当集合中有任何一个的项时,都没有问题。然而,当列表B中没有项目时,我会在"foreach"行上得到一个"Object reference not set to a instance of a Object"Exception。但是,列表A不会出现这种情况。
我更进一步,为了安全起见,修改了上面的代码,使其看起来如下:
if (a.Count > 0)
{
foreach (MyType myA in a)
{
//DO STUFF HERE
}
}
if (b.Count > 0)
{
foreach (MyType myB in b)
{
//DO STUFF HERE
}
}
通过"A"列表的迭代可以很好地进行,无论它是空集合还是有元素。如果集合中有元素,则通过"B"列表的迭代再次进行,但除了这次在(myB.Count) > 0
行之外,再次抛出相同的异常。通过调试,当集合为空时(正如我所期望的),两个集合的Count属性都显示"0"。
自定义"MyType"类有一个默认构造函数,其中所有非虚拟变量都声明为:
namespace MyApp.Models
{
public class MyType
{
public int ID { get; set; }
public string Code { get; set; }
public int ParentID { get; set; }
[ScriptIgnore(ApplyToOverrides = true)]
[JsonIgnore]
public virtual Parent Parent { get; set; }
public MyType()
{
ID = 0;
Code = null;
ParentID = 0;
}
}
}
我有点不知所措。我还有其他自定义类型在这里也失败了,但事实上,这种相同类型的配对,其中一个通过得很好,另一个抛出异常,这对我来说是可疑的,希望能帮助我了解这种行为。
如果myB
为空,myB.Count
将引发异常。你应该先检查空:
if(myB != null && myB.Count > 0)
为了安全起见,你可能还想对你的第一份清单这样做。。。您可以取消Count
检查,这是不必要的。如果集合为空,foreach
不会抛出异常,它只在您尝试迭代null集合时抛出,因为foreach
在您的集合上调用GetEnumerator
方法,这会导致异常。
如果a
或b
为null,则不能对其调用函数。您将获得null引用异常。所以请检查它们是否为空。
if(a !=null)
{
foreach (MyType myA in a)
{
//DO STUFF HERE
}
}
不需要在foreach
表达式之前检查计数。如果它是空的,那么它基本上跳过循环。
问题在于您假设a
和b
永远不是null
。如果输入不是json,或者在结构上与您的类型的定义有很大不同,那么这些引用将为null,然后当您尝试迭代null时,您将崩溃。
您只需要为每个集合使用if ( a != null ) // iterate
,因此,您应该在从DeserializeObject<T>
分配的任何时候进行无效性检查
不能对null
集合进行迭代,因为foreach
将对提供的IEnumerable
参数隐式调用GetEnumerator()
。在foreach
子句中使用默认值之前,必须为b
指定一个默认值,或者检查它是否不是null
。
if ((b != null) && (b.Count > 0))
{
foreach (MyType myB in b)
{
//DO STUFF HERE
}
}
因为我不知道jsonstringa的值或jsonstringb的值是什么。我猜jsonsringb将是一个空字符串,因为你指的是没有项的情况。空字符串将被视为格式错误的JSON字符串。的结果
JsonConvert.DeserializeObject
当给定格式错误的JSON字符串时,它将返回null而不是空列表。这意味着,如果jsonstringb格式错误或为空字符串,则b为null。这就是为什么每当你请求b.Count或对b执行foreach(foreach将对b调用GetEnumerator方法)时,你都会得到一个null引用异常。因此,在调用JsonConvert.DeserializeObject之前,您可以执行以下操作来检查jsonstringb的值,确保它不是空的或null,如果是,则使其成为空数组。
if(string.IsNullOrEmpty(jsonstringb)){
jsonstringb = "[]";
}
然后呼叫
List<MyType> b = JsonConvert.DeserializeObject<List<MyType>>(jsonstringb);
在循环或调用列表上的方法之前,不要忘记检查null。
if (b!=null){
//Your loop or Count here!
};
另一种检查集合是否有元素的方法是使用any()而不是Count。
if(b.Any()){
//you have elements in b
}