【问题标题】:Why is this code throwing an ArgumentNullException?为什么这段代码会抛出 ArgumentNullException?
【发布时间】:2010-02-14 13:51:08
【问题描述】:

我在整个过程中都使用此代码模式,并且仅在此特定属性中,在尝试为其分配值时(即调用 setter)会引发 ArgumentNullException。为null的对象是isLoggedInLock,所以在调用setter之前它似乎没有被实例化。瓦特错了??

编辑:我注释掉了 OnPropertyChanged 方法以避免混淆。仍然抛出异常。我能想到的另一件事是更新是在 UI 线程之外的另一个线程中完成的。

EDIT2:我在非静态构造函数中实例化了 isLoggedInLock ,但仍然抛出异常。一些非常奇怪的事情正在发生。我会进一步调查。

最后编辑:我的道歉:我遗漏了解决方案的关键:[DataMember] 属性。该对象通过反序列化来实现。这将跳过默认构造函数和 isLoggedInLock 的静态初始化。通过使用 [DataMember] 属性装饰 isLoggedInLock 或在使用 [OnDeserialzed] 属性装饰的方法中实例化它,问题就消失了!

非常感谢,第一个更新他的答案的人将获得积分! ;-)

    [DataMember]
    private bool isLoggedIn;
    private readonly object isLoggedInLock=new object();
    public bool IsLoggedIn
    {
        get
        {
            lock (isLoggedInLock)
            {
                return isLoggedIn; 
            }
        }
        set
        {
            lock (isLoggedInLock)
            {
                isLoggedIn = value;
                //OnPropertyChanged("IsLoggedIn");
            }
        }
    }

【问题讨论】:

  • OnPropertyChanged方法中有代码吗?
  • 请捕获异常并发布 ex.ToString() 的结果
  • 这是ArgumentNullException 还是NullReferenceException,就像您标记的那样?
  • ArgumentNullException,标签不准确

标签: c# .net


【解决方案1】:

在您发布的代码中引发 ArgumentNullException 的唯一原因是当您执行 lock 语句时 isLoggedInLock 为 null。因此,除非您在其他地方明确将 isLoggedInLock 设置为 null(并且这只能在构造函数中,因为该字段是只读的),否则您的假设是正确的:

好像没有 在 setter 之前实例化 叫

字段将按照声明的顺序进行初始化,因此,如果您有一个更高级别的字段初始化调用访问 IsLoggedIn 属性的成员,这将在 isLoggedInLock 初始化之前发生。

如果您从异常中查看堆栈跟踪,应该很容易弄清楚发生了什么。

【讨论】:

    【解决方案2】:

    从 10 秒查看代码来看,最可能的原因是 OnPropertyChanged。

    我猜测它引发了一个事件的命名。我们可以看到这个方法的代码吗?很有可能它在调用事件处理程序之前没有先进行空检查以检查是否有人订阅。

    [编辑 - 抱歉没有读到您将 isLoggedInLock 确定为罪魁祸首]

    你确定它是isLoggedInLock - 因为看起来这个为空的范围不大。由于它被标记为只读,因此不可能在方法的其他地方设置为 null。

    这是受影响代码的准确表示吗?绝对不是属性是静态的,还是这样的差异?

    【讨论】:

      【解决方案3】:

      你有静态构造函数吗? (它是否使用 IsLoggedIn ?)

      【讨论】:

        【解决方案4】:

        一个类的字段可能是空的,即使它在构造函数中被初始化:当类通过反序列化进入生命时,构造函数不是 叫……

        【讨论】:

          【解决方案5】:

          是否可能,反射被设置为“isLoggedInLock”为空?使用 FieldInfo.SetValue() 您可以更改只读字段的值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-18
            相关资源
            最近更新 更多