我正在尝试创建一个如下所示的JsonConverter
:
abstract
个class
和interface
s 其工作方式示例:
如果有
/// <summary>
/// Interface with multiple non-conflicting implementations
/// </summary>
[JsonConverter(typeof(PolyJsonConverter))]
private interface IBar
{
string StringProperty { get; }
}
private class Bar1 : IBar
{
public string StringProperty { get; set; }
public string OtherStringProperty { get; set; }
}
private class Bar2 : IBar
{
public string StringProperty { get; set; }
public double[] DoubleArrayProperty { get; set; }
}
然后这是应该通过的测试
[TestMethod]
public void InterfaceWithNonConflictingImplementationsDerivedFromOtherInterfaceCanSerializeAndDeserializeToBaseInterfaceTest()
{
var concreteBaz = new Baz1()
{
StringProperty = "blah blah",
IntArrayProperty = new int[] { 1, 2, 3 }
};
string json = JsonConvert.SerializeObject(concreteBaz);
IBar bar = JsonConvert.DeserializeObject<IBar>(json);
Assert.IsNotNull(bar);
Assert.AreEqual(concreteBaz.StringProperty, bar.StringProperty);
}
除了ReadJson
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
string json = jObject.ToString();
var derivedTypes = GetDerivedTypes(objectType);
object match = null;
foreach (var dervivedType in derivedTypes)
{
object deserialized;
try
{
deserialized = JsonConvert.DeserializeObject(json, dervivedType, requiredSerializerSettings);
}
catch
{
continue;
}
if (match != null)
{
if (conflictResolutionMode == ConflictResolutionMode.ThrowError)
{
throw new JsonException($"Multiple matching implementations found for base type {objectType}.");
}
}
else
{
match = deserialized;
if (conflictResolutionMode == ConflictResolutionMode.UseArbitrary)
{
break;
}
}
}
if (match == null)
{
throw new JsonException($"Could not find match for type {objectType} among derived types {string.Join(", ", derivedTypes)}.");
}
return match;
}
private static IEnumerable<Type> GetDerivedTypes(Type baseType)
{
return derivedTypesCache.GetOrAdd(baseType, t => QueryDerivedTypes(t));
}
private static IEnumerable<Type> QueryDerivedTypes(Type baseType)
{
return from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
from assemblyType in domainAssembly.GetTypes()
where baseType.IsAssignableFrom(assemblyType)
&& !assemblyType.IsInterface
&& !assemblyType.IsAbstract
select assemblyType;
}
我理解“为什么”,但我不知道如何解决。有什么想法吗?