你可以使用
自定义引用解析器。例如,假设
Name
是你的对象的"主键",这应该能够工作。当然,你可能想要使它更通用化。
public class PersonReferenceResolver : IReferenceResolver
{
private readonly IDictionary<string, Person> _objects =
new Dictionary<string, Person>();
public object ResolveReference(object context, string reference)
{
Person p;
if (_objects.TryGetValue(reference, out p))
{
return new Person
{
Name = p.Name,
BirthDate = p.BirthDate,
LastModified = p.LastModified
};
}
return null;
}
public string GetReference(object context, object value)
{
Person p = (Person)value;
_objects[p.Name] = p;
return p.Name;
}
public bool IsReferenced(object context, object value)
{
Person p = (Person)value;
return _objects.ContainsKey(p.Name);
}
public void AddReference(object context, string reference, object value)
{
_objects[reference] = (Person)value;
}
}
现在你可以像这样反序列化:
var jsonSerializerSettings = new JsonSerializerSettings()
{
ReferenceResolver = new PersonReferenceResolver()
};
var deserializedPersons = JsonConvert.DeserializeObject<List<Person>>(
json, jsonSerializerSettings);
编辑:我感到无聊,所以我制作了一个通用版本:
public class GenericResolver<TEntity> : IReferenceResolver
where TEntity : ICloneable, new()
{
private readonly IDictionary<string, TEntity> _objects = new Dictionary<string, TEntity>();
private readonly Func<TEntity, string> _keyReader;
public GenericResolver(Func<TEntity, string> keyReader)
{
_keyReader = keyReader;
}
public object ResolveReference(object context, string reference)
{
TEntity o;
if (_objects.TryGetValue(reference, out o))
{
return o.Clone();
}
return null;
}
public string GetReference(object context, object value)
{
var o = (TEntity)value;
var key = _keyReader(o);
_objects[key] = o;
return key;
}
public bool IsReferenced(object context, object value)
{
var o = (TEntity)value;
return _objects.ContainsKey(_keyReader(o));
}
public void AddReference(object context, string reference, object value)
{
if(value is TEntity)
_objects[reference] = (TEntity)value;
}
}
稍微有些新的用法:
var jsonSerializerSettings = new JsonSerializerSettings()
{
//Now we need to specify the type and how to get the object's key
ReferenceResolver = new GenericResolver<Person>(p => p.Name)
};
var deserializedPersons = JsonConvert.DeserializeObject<List<Person>>(
json, jsonSerializerSettings);