如何在C#中打印任意变量以打印所有成员?
我用相同的技术找到了三个答案:
但是,当我尝试使用以下代码进行测试时,
using System; using System.Collections.Generic; using Newtonsoft.Json; public static class Program { public static void Main() { Test t1 = new Test(1, 2); { string json = JsonConvert.SerializeObject(t1, Formatting.Indented); Console.WriteLine(json); } Dump(t1); // Add 3 objects to a List. List<Test> list = new List<Test>(); list.Add(new Test(1, 2)); list.Add(new Test(3, 4)); list.Add(new Test(5, 6)); Console.WriteLine(list.ToString()); { string json = JsonConvert.SerializeObject(list, Formatting.Indented); Console.WriteLine(json); } } public class Test { int A; int b; public Test(int _a, int _b) { A = _a; b = _b; } }; public static void Dump<T>(this T x) { string json = JsonConvert.SerializeObject(x, Formatting.Indented); Console.WriteLine(json); } }
我得到的只是空Test输出:
Test
{} {} System.Collections.Generic.List`1[Program+Test] [ {}, {}, {} ]
使用Json.NET序列化为JSON时,为什么所有类成员都丢失了?
默认情况下,Json.NET将仅序列化 公共 属性和字段。您的字段A和b是 私有的 。要使非公共(私有或内部)成员被Json.NET序列化,您可以:
A
b
public int A; public int b;
但是,从风格上讲,如果要使其公开,最好将它们转换为属性:
public class Test { public int A { get; private set; } public int b { get; private set; } public Test(int a, int b) { this.A = a; this.b = b; } };
对于Json.NET,只有获取器需要公开才能序列化它们。
[JsonProperty]
[JsonProperty] int A; [JsonProperty] int b;
这也适用于非公共财产。
[DataContract]
[DataMember]
[DataContract] public class Test { [DataMember] int A; [DataMember] int b; public Test(int _a, int _b) { A = _a; b = _b; } };
请注意,数据合同序列化是可选的,因此您需要使用标记 每个 要序列化的成员[DataMember]。有点麻烦,但如果您不希望c#模型依赖于Json.NET,则很有用。
[JsonObject(MemberSerialization = MemberSerialization.Fields)]
[JsonObject(MemberSerialization = MemberSerialization.Fields)] public class Test { // Remainder as before... };
由于在解释文件的MemberSerialization,MemberSerialization.Fields可确保
MemberSerialization
MemberSerialization.Fields
所有公共和私有字段都已序列化。可以使用JsonIgnoreAttribute或NonSerializedAttribute排除成员。也可以通过使用SerializableAttribute标记该类并将DefaultContractResolver上的IgnoreSerializableAttribute设置为false来设置此成员序列化模式。
当然,这只会导致非公共 字段 被序列化,而不是非公共属性,但是如果您的目的是出于调试目的而 打印任意变量 ,则可能需要这样做。
将属性和公共或私有字段进行序列化。
另一个方法是 使用JSON.NET继承的私有字段DeclaredFieldContractResolver从_C#序列化开始,通过自动假定所有对象都标记为,仅序列化公共字段或私有字段MemberSerialization.Fields`。您可以这样使用它:
DeclaredFieldContractResolver
化开始,通过自动假定所有对象都标记为,仅序列化公共字段或私有字段
var settings = new JsonSerializerSettings { ContractResolver = DeclaredFieldContractResolver.Instance }; var json = JsonConvert.SerializeObject(t1, Formatting.Indented, settings);
JsonConverter
public class Test
{ public class TestJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(Test).IsAssignableFrom(objectType); }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var test = (Test)value; writer.WriteStartObject(); writer.WritePropertyName(nameof(Test.A)); serializer.Serialize(writer, test.A); writer.WritePropertyName(nameof(Test.b)); serializer.Serialize(writer, test.b); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } } // Remainder as before
}
并像这样使用它:
var json = JsonConvert.SerializeObject(t1, Formatting.Indented, new Test.TestJsonConverter());
在这种情况下,由于类型是嵌套的,因此您的模型仍将依赖于Json.NET,这使选项#2成为更好的选择。
如果仅出于调试目的转储对象,则#5可能是最佳选择。