I'm getting a null exception, but the field was initialized as an empty list. So how could it be null?
The error occurs on the second line in this method (on _hydratedProperties):
protected virtual void NotifyPropertyChanged<T>(Expression<Func<T>> expression)
{
string propertyName = GetPropertyName(expression);
if (!this._hydratedProperties.Contains(propertyName)) { this._hydratedProperties.Add(propertyName); }
}
And this is how the field is declared:
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
private List<string> _hydratedProperties = new List<string>();
This is how it's set:
public Eta Eta
{
get { return this._eta; }
set
{
this._eta = value;
NotifyPropertyChanged(() => this.Eta);
}
}
This is the full class (with the comments and non-relevant parts removed):
[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;
}
}
Derived class:
[DataContract]
public class Bin : EntityBase<Bin>
{
private Eta _eta;
[DataMember]
public Eta Eta
{
get { return this._eta; }
set
{
this._eta = value;
NotifyPropertyChanged(() => this.Eta);
}
}
}
SELECT * FROM yourTableName WHERE yourSpecificColumnName IS NULL OR yourSpecificColumnName = ' '; The IS NULL constraint can be used whenever the column is empty and the symbol ( ' ') is used when there is empty value.
The ISNULL() function returns a specified value if the expression is NULL. If the expression is NOT NULL, this function returns the expression.
NULL is used in SQL to indicate that a value doesn't exist in the database. It's not to be confused with an empty string or a zero value. While NULL indicates the absence of a value, the empty string and zero both represent actual values.
Here's the clue:
[DataContract]
Yup. DataContractSerializer
does not call any constructor. Instead, it uses FormatterServices.GetUninitializedObject
to create the object that will be deserialized. This bypasses the constructor call.
Your initializer:
private List<string> _hydratedProperties = new List<string>();
is translated to an implicit default constructor by the compiler.
As a workaround, you can use a deserialization callback with 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
}
I found a simpler answer than what Lucas provided. I'm not sure if this one is actually better, but it's simple and it worked. All I did was add the DataMember
attribute to the field. Since that specifies that the field is part of the data contract, it is included with serialization/deserialization and no longer causes a null reference error.
[DataContract]
public abstract class EntityBase<TSubclass> : INotifyPropertyChanged where TSubclass : class
{
[DataMember]
private List<string> _hydratedProperties = new List<string>();
// More code here
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With