尝试枚举自定义类型列表时抛出异常

时间:2014-04-24 20:45:49

标签: c# asp.net entity-framework asp.net-mvc-4 nullreferenceexception

我有两个通过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”行上抛出异常。但是,对于列表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;
        }
    }
}

我有点不知所措。我有其他自定义类型也在这里失败,但事实上,这个相同类型的配对与一个通过正常和另一个抛出异常是我怀疑,并希望可以帮助有人给我一些关于这种行为的见解。

5 个答案:

答案 0 :(得分:1)

如果myB为空myB.Count将抛出异常。您应首先检查null:

if(myB != null && myB.Count > 0)

您可能还希望使用第一个列表执行此操作以确保安全...并且您可以删除Count检查,这是不必要的。如果集合是foreach将不会抛出异常> empty ,它只会在您尝试迭代 null 集合时抛出,因为foreach调用集合上的GetEnumerator方法导致异常。< / p>

答案 1 :(得分:0)

如果ab为空,则无法调用其中的函数。你会得到一个空引用异常。所以检查它们是否为空。

if(a !=null)
{
    foreach (MyType myA in a)
    {
       //DO STUFF HERE
    }
}

没有明确需要在foreach表达式之前检查计数。如果它是空的,那么它基本上会跳过循环。

答案 2 :(得分:0)

问题在于您假设ab永远不会null。如果输入不是json,或者在结构上与你的类型的定义有很大不同,那么这些引用将为null,然后当你尝试迭代null时你会崩溃。

每个集合只需要if ( a != null ) // iterate,因此,无论何时从DeserializeObject<T>分配

,都应该进行无效检查

答案 3 :(得分:0)

您无法迭代null的集合,因为foreach会在提供的GetEnumerator()参数上隐式调用IEnumerable。您必须先为b分配默认值,或在null子句中使用它之前检查它是否为foreach

if ((b != null) && (b.Count > 0)) 
{
    foreach (MyType myB in b)
    {
       //DO STUFF HERE
    }
}

答案 4 :(得分:0)

因为我不知道jsonstringa的值或jsonstringb的值是什么。我猜想jsonstringb将是一个空字符串,因为你指的是没有项目时的情况。空字符串将被视为格式错误的JSON字符串。

的结果
JsonConvert.DeserializeObject

当给出格式错误的JSON字符串时,将返回null而不是空列表。这意味着如果jsonstringb格式错误或空字符串,则b为null。这就是为什么每当你要求b.Count或在b上做foreach(foreach将在b上调用GetEnumerator方法)时,你将得到一个空引用异常。因此,在调用JsonConvert之前,您可以执行以下检查jsonstringb的值。确保它不为空,如果是,则将其设为空数组。

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
}