这个字段怎么是空的
本文关键字:字段 | 更新日期: 2023-09-27 18:27:21
我得到一个null异常,但字段被初始化为空列表。那么它怎么可能是空的呢?
错误出现在此方法的第二行(在_hydratedProperties上):
protected virtual void NotifyPropertyChanged<T>(Expression<Func<T>> expression)
{
string propertyName = GetPropertyName(expression);
if (!this._hydratedProperties.Contains(propertyName)) { this._hydratedProperties.Add(propertyName); }
}
这就是字段的声明方式:
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
private List<string> _hydratedProperties = new List<string>();
这就是它的设置:
public Eta Eta
{
get { return this._eta; }
set
{
this._eta = value;
NotifyPropertyChanged(() => this.Eta);
}
}
这是完整的类别(删除了注释和非相关部分):
[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
private List<string> _hydratedProperties = new List<string>();
public bool IsPropertyHydrated(string propertyName)
{
return this._hydratedProperties.Contains(propertyName);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged<T>(Expression<Func<T>> expression)
{
string propertyName = GetPropertyName(expression);
if (!this._hydratedProperties.Contains(propertyName)) { this._hydratedProperties.Add(propertyName); }
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public string GetPropertyName<T>(Expression<Func<T>> expression)
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
return memberExpression.Member.Name;
}
}
派生类:
[DataContract]
public class Bin : EntityBase<Bin>
{
private Eta _eta;
[DataMember]
public Eta Eta
{
get { return this._eta; }
set
{
this._eta = value;
NotifyPropertyChanged(() => this.Eta);
}
}
}
以下是线索:
[DataContract]
是的。DataContractSerializer
不调用任何构造函数。相反,它使用FormatterServices.GetUninitializedObject
来创建将被反序列化的对象。这将绕过构造函数调用。
您的初始值设定项:
private List<string> _hydratedProperties = new List<string>();
由编译器转换为隐式默认构造函数。
作为一种变通方法,您可以使用带有OnDeserializingAttribute
:的反序列化回调
[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged
where TSubclass : class
{
private List<string> _hydratedProperties;
protected EntityBase()
{
Init();
}
private void Init()
{
_hydratedProperties = new List<string>()
}
[OnDeserializing]
private void OnDeserializing(StreamingContext context)
{
Init();
}
// ... rest of code here
}
我找到了一个比Lucas提供的更简单的答案。我不确定这个是否真的更好,但它很简单,而且很有效。我所做的只是将DataMember
属性添加到字段中。由于这指定字段是数据协定的一部分,因此它包含在序列化/反序列化中,不再导致null引用错误。
[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
[DataMember]
private List<string> _hydratedProperties = new List<string>();
// More code here
}