我有一个类,它有一个集合是readonly
,没有setter。
是否有一种方法来反序列化一些json,并让它调用实例上的方法,而不是属性setter?
例如:public class User
{
private ObservableCollection<Movie> _movies;
public string Name { get; set; }
public ReadOnlyCollection<Movie> FavouriteMovies { get; set; }
public void AddMovie(Movie movie) { .. }
//-or-
public void AddMovies(IEnumerable<Movie> movies){ .. }
}
使事物进入_movies
后备场的唯一方法是通过AddMovies
方法。因此,当试图反序列化一些有效的json json中有一个数组的电影,它将调用AddMovie
或AddMovies
…
忍者更新由PK:
根据下面的答案,我使用类的集合而不是简单的字符串来分叉下面的代码,以获得一个现在可以工作的更复杂的示例。
使用JsonConverter
做json的自定义转换。这里有一个简单的例子来说明它是如何工作的。给定这样一个类:
public class MyClass
{
private List<string> backingField;
public string Name { get; set; }
public IReadOnlyCollection<string> MyStrings { get; private set; }
public MyClass()
{
backingField = new List<string>();
MyStrings = backingField.AsReadOnly();
}
public void AddString(string item)
{
backingField.Add(item);
}
}
JSON像这样:
{
"MyStrings": [
"Foo",
"Bar"
],
"Name":"My stuff"
}
你可以创建一个转换器来读取json,并调用AddString
来填充backingField
,像这样:
public class MyClassConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var obj = new MyClass();
var jObj = JObject.Load(reader);
JsonConvert.PopulateObject(jObj.ToString(), obj); // populate fields we don't need any special handling for
var stringsProp = jObj["MyStrings"];
if (stringsProp != null)
{
var strings = stringsProp.ToObject<List<string>>();
foreach (var s in strings)
{
obj.AddString(s);
}
}
return obj;
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(MyClass);
}
}
现在要使用它,并且不让MyClass
知道它是如何反序列化的,您可以简单地这样做:
var m = JsonConvert.DeserializeObject(json, typeof(MyClass), new MyClassConverter()) as MyClass;
Here's fiddle