我有一个readonly struct(Outer),它有一个readonly结构属性(Inner),它作为in
参数传递给构造函数,以避免在调用构造函数时出现一个副本。尝试反序列化外部导致Json.Net被in
参数混淆:
using System;
using Newtonsoft.Json;
namespace DeserializeTest
{
public readonly struct Inner
{
[JsonConstructor]
public Inner(int i) => I = i;
public int I { get; }
}
public readonly struct Outer
{
[JsonConstructor]
public Outer(in Inner inner) => Inner = inner;
public Inner Inner { get; }
}
public class Program
{
public static void Main()
{
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine();
try
{
var originalOuter = new Outer(new Inner(1));
var json = JsonConvert.SerializeObject(originalOuter);
var newOuter = JsonConvert.DeserializeObject<Outer>(json);
Assert.IsTrue(originalOuter.Inner.I == newOuter.Inner.I);
Console.WriteLine(json);
}
catch (Exception ex)
{
Console.WriteLine("Failed with unhandled exception: ");
Console.WriteLine(ex);
throw;
}
}
}
public class AssertionFailedException : Exception
{
public AssertionFailedException(string s) : base(s) { }
}
public static class Assert
{
public static void IsTrue(bool value)
{
if (!value)
{
throw new AssertionFailedException("failed");
}
}
}
}
这导致了这个输出:
Environment version: 4.0.30319.42000
Json.NET version: Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type DeserializeTest.Inner&. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Inner.I', line 1, position 14.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at DeserializeTest.Program.Main() in e:\projects\DeserializeTest\DeserializeTest\Program.cs:line 31