鉴于:
public class MyClass : INotifyPropertyChanged
{
public List<string> _TestFire = new List<string>();
string _StringProp;
public string StringProp
{
get
{
return _StringProp;
}
set
{
if (_StringProp != value)
{
_StringProp = value;
RaisePropertyChanged("StringProp");
_TestFire.Add("fired " + DateTime.Now);
}
}
}
}
当你序列化然后反序列化这个类时,它会触发RaisePropertyChanged
事件,这是不可取的。是否有可能在类反序列化时阻止此事件被触发?
var MyclassInstance = new MyClass() { StringProp = "None" };
MyclassInstance._TestFire.Clear(); // Clear property change history
var serobj = JsonConvert.SerializeObject();
var newitem = JsonConvert.DeserializeObject<MyClass>(serobj);
// newitem._TestFire.Count == 1, the set method was executed
如果要对该类进行反序列化,是否有办法获得bool
值?那么我可以这样做:
set
{
if (_StringProp != value)
{
_StringProp = value;
if (!Deserializing)
{
RaisePropertyChanged("StringProp");
_TestFire.Add("fired " + DateTime.Now);
}
}
}
是的,你可以通过在课堂上实施OnDeserializing
和OnDeserialized
serialization callback methods来做你想做的事。在OnDeserializing
方法中,将私有_isDeserializing
变量设置为true,并在OnDeserialized
中将其设置为false。我建议在_isDeserializing
方法中进行RaisePropertyChanged
检查,这样你就不会在每个属性中都有重复的代码。
所以你最终得到这样的东西:
public class MyClass : INotifyPropertyChanged
{
public List<string> _TestFire = new List<string>();
string _StringProp;
public string StringProp
{
get
{
return _StringProp;
}
set
{
if (_StringProp != value)
{
_StringProp = value;
RaisePropertyChanged("StringProp");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
// don't raise the event if the property is being changed due to deserialization
if (_isDeserializing) return;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
_TestFire.Add(propertyName + " was fired " + DateTime.Now);
}
bool _isDeserializing = false;
[OnDeserializing]
internal void OnDeserializingMethod(StreamingContext context)
{
_isDeserializing = true;
}
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
_isDeserializing = false;
}
}
工作演示:https://dotnetfiddle.net/QkOcF4
解决此问题的另一种方法是使用[JsonIgnore]
标记公共属性,然后使用[JsonProperty]
标记相应的支持字段,指定要在JSON中使用的属性名称。这将允许Json.Net直接设置支持字段而不执行任何mutator逻辑。
public class MyClass : INotifyPropertyChanged
{
public List<string> _TestFire = new List<string>();
[JsonProperty("StringProp")]
string _StringProp;
[JsonIgnore]
public string StringProp
{
get
{
return _StringProp;
}
set
{
if (_StringProp != value)
{
_StringProp = value;
RaisePropertyChanged("StringProp");
_TestFire.Add("StringProp was fired " + DateTime.Now);
}
}
}
...
}