【问题标题】:Can't find the reason for this NullReferenceException找不到此 NullReferenceException 的原因
【发布时间】:2011-01-20 09:31:06
【问题描述】:

我有以下方法:

internal static void removeMethodFromTag(byte p, Method method)
        {
            Console.WriteLine("Remove method " + method.getName() + " from the tag");
            List<Method> outList = new List<Method>();
            methodTaggings.TryGetValue(p, out outList);
            Console.WriteLine(outList.Count);
            outList.Remove(method);
            methodTaggings.Remove(p);
            methodTaggings.Add(p, outList);
        }

这是字典方法标记:

private static Dictionary<byte, List<Method>> methodTaggings = new Dictionary<byte, List<Method>>();

现在我总是在行中得到NullReferenceException

Console.WriteLine(outList.Count);

但我不明白为什么?即使我在字典中没有找到值,列表也不应该为空?

【问题讨论】:

  • 我可以告诉你,outList 似乎可能设置为 nullMSDN 说:“如果找到键;否则,为 value 参数类型的默认值。”。列表的默认类型是null。不过不确定。
  • 啊,谢谢,我一直以为列表不会只包含任何元素。
  • 您可以设置 Visual Studio 以立即在 Throw for NullReferenceException 上中断。然后,您将在导致 NullReferenceException 的行中出现中断并可以进行调试。

标签: c# .net wpf exception


【解决方案1】:

这不应该是:

internal static void removeMethodFromTag(byte p, Method method)
        {
            Console.WriteLine("Remove method " + method.getName() + " from the tag");
            List<Method> outList = new List<Method>();
            if (methodTaggings.TryGetValue(p, out outList);
            {
              Console.WriteLine(outList.Count);
              outList.Remove(method);
              methodTaggings.Remove(p);
              methodTaggings.Add(p, outList);
           }
        }

【讨论】:

  • 不! MethodTaggings 可以为 p 参数包含 null 值 outList,所以问题不会被修复!!!
【解决方案2】:

在 TryGetValue 方法中添加一个 if。我认为 TryGetValue 在失败时会将 out 变量设置为 null。

internal static void removeMethodFromTag(byte p, Method method)
        {
            Console.WriteLine("Remove method " + method.getName() + " from the tag");
            List<Method> outList = new List<Method>();
            if(methodTaggings.TryGetValue(p, out outList)) {
                Console.WriteLine(outList.Count);
                outList.Remove(method);
                methodTaggings.Remove(p);
                methodTaggings.Add(p, outList);
            }
        }

【讨论】:

    【解决方案3】:

    我可以在这里看到的唯一嫌疑人是这一行:

    methodTaggings.TryGetValue(p, out outList);
    

    难道参数pmethodTaggings.TryGetValue居然把outList设置成了null

    在这一行下下断点,我想你会看到,越过这一行后,outList 将是null

    【讨论】:

      【解决方案4】:

      可以通过TryGetValue的算法初始化为nullout 参数总是被初始化 insed 方法被调用。 而且您的代码不需要这一行:

      List<Method> outList = new List<Method>();
      

      如果您使用某些需要 ref(而不是 out)参数的方法,那么您将需要它。但在这里。 详情请参考:http://www.c-sharpcorner.com/UploadFile/mahesh/UsingtheoutParameter12232005041002AM/UsingtheoutParameter.aspx

      【讨论】:

        【解决方案5】:

        无需在代码中分配outList,因为您通过其第二个参数将其传递给TryGetValue(),该参数声明为out parameter

        我的猜测是TryGetValue()null 分配给outList

        【讨论】:

          【解决方案6】:

          TryGetValue 正在将您的 outList 替换为其默认值 null

          【讨论】:

            【解决方案7】:

            您的错误是在您调用 TryGetValue 时。参数outList 被标记为out,所以你原来的空列表在那里丢失了。

            【讨论】:

              【解决方案8】:

              无论TryGetValue是否成功,列表的值将不再存在,即使您在调用之前已为其赋值。一个简单的例子:

              int num = 9;
              int.TryParse("abc", out num);
              

              TryParse明显失败了,原来的9不会保留。

              【讨论】:

                【解决方案9】:

                来自MSDN

                如果没有找到key,则value参数获取值类型TValue的相应默认值;例如,整数类型为 0(零),布尔类型为 false,引用类型为 null。

                List&lt;Method&gt; 是一个引用类型,所以它会返回null

                祝你好运!

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-12-29
                  • 2022-11-24
                  • 2019-12-28
                  • 2018-08-04
                  相关资源
                  最近更新 更多