我一直使用此代码模式,仅在尝试为该属性分配值(即调用设置器)时,会在此特定属性中抛出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");
}
}
}
最佳答案
可以在发布的代码中引发ArgumentNullException的唯一原因是,在执行lock语句时,如果isLoggedInLock为null。因此,除非您在其他位置将isLoggedInLock显式设置为null(并且由于字段是只读的,所以只能在构造函数中使用),否则您的假设是正确的:
似乎还没有
在setter之前实例化
叫
字段将按照声明的顺序进行初始化,因此,如果您有一个更高级别的字段初始化来调用访问IsLoggedIn属性的成员,则将在isLoggedInLock初始化之前进行。
如果您从异常中查看堆栈跟踪,则应该很容易弄清正在发生的情况。