C# 这个字段怎么为空?

C# 这个字段怎么为空?,c#,C#,我得到一个空异常,但该字段被初始化为空列表。那么它怎么可能是空的呢 此方法中的第二行出现错误(在_hydratedProperties上): 这是完整类(删除注释和非相关部分): [DataContract] 公共抽象类EntityBase:INotifyPropertyChanged,其中TSubclass:class { 私有列表_hydratedProperties=新列表(); public bool IsPropertyHydrated(字符串propertyName) { 返回此。\

我得到一个空异常,但该字段被初始化为空列表。那么它怎么可能是空的呢

此方法中的第二行出现错误(在_hydratedProperties上):

这是完整类(删除注释和非相关部分):

[DataContract]
公共抽象类EntityBase:INotifyPropertyChanged,其中TSubclass:class
{
私有列表_hydratedProperties=新列表();
public bool IsPropertyHydrated(字符串propertyName)
{
返回此。\u hydratedProperties.Contains(propertyName);
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void NotifyPropertyChanged(表达式)
{
字符串propertyName=GetPropertyName(表达式);
如果(!this._hydratedProperties.Contains(propertyName)){this._hydratedProperties.Add(propertyName);}
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共字符串GetPropertyName(表达式)
{
MemberExpression MemberExpression=(MemberExpression)expression.Body;
返回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]
公共类Bin:EntityBase
{
私人埃塔;
[数据成员]
公众预计到达时间
{
获取{返回此。_eta;}
设置
{
这是._eta=值;
NotifyPropertyChanged(()=>this.Eta);
}
}
}
以下是线索:

[DataContract]
是的。相反,它使用
FormatterServices.GetUninitializedObject
创建将被反序列化的对象。这将绕过构造函数调用

您的初始值设定项:

private List<string> _hydratedProperties = new List<string>();

我找到了一个比卢卡斯提供的更简单的答案。我不确定这一个是否真的更好,但它很简单而且有效。我所做的只是将
DataMember
属性添加到字段中。因为这指定字段是数据协定的一部分,所以它包含在序列化/反序列化中,不再导致空引用错误

[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
    [DataMember]
    private List<string> _hydratedProperties = new List<string>();

    // More code here
}
[DataContract]
公共抽象类EntityBase:INotifyPropertyChanged,其中TSubclass:class
{
[数据成员]
私有列表_hydratedProperties=新列表();
//这里有更多代码
}

可能重复@BobHorn您是否碰巧从多个线程写入列表?如果是这样,您可能需要实现锁或使用线程安全集合我们确实需要准确的错误消息(包括提到的任何变量)和复制错误的代表性代码示例。我认为他知道什么是null异常,现在他知道什么是null是隐藏属性。他需要知道为什么。从使用notify属性更改,可能处于数据绑定状态。可能是线程问题,很难说。@Grundy这不是重复的。这个问题是问为什么它抛出了
NullReferenceException
而不是
NullReferenceException
…卢卡斯:我刚才发布的答案呢?这也是解决这个问题的一种可以接受的方法吗?这同样有效,但是属性列表显然也会被序列化。我不知道你的代码能告诉你这对你是好是坏,但它可能会产生意想不到的后果,你应该注意:如果你需要进行版本控制,并且你反序列化了以前版本的类,您将重新获得旧列表-您希望在该列表中的任何属性以及您以后添加的属性将不再存在-这可能会破坏您的代码,具体取决于您以后对其所做的操作。它还将使用冗余数据增加有效负载大小。但是如果你觉得这一切都好的话,那当然,继续吧。谢谢你,卢卡斯。围绕此代码的逻辑仅在内存中,而不是持久化的,因此版本控制不是问题。这是一个关于有效载荷的好观点。
[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]
private List<string> _hydratedProperties = new List<string>();
[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
}
[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
    [DataMember]
    private List<string> _hydratedProperties = new List<string>();

    // More code here
}