ValueTuples 在序列化时丢失了它们的 属性 名称

ValueTuples lose their property names when serialized

在尝试将命名值元组序列化为 JSON 字符串时,它丢失了分配给项目的名称

(string type, string text) myTypes = ("A", "I am an animal");
var cnvValue = JsonConvert.SerializeObject(myTypes);

我希望序列化值为

{"type":"A","text":"I am an animal"}

但实际结果是

{"Item1":"A","Item2":"I am an animal"}

有两件事我很想知道

名称是编译器的把戏。如果您查看 ValueTuple 的定义,您会看到它的字段名称只是 Item1Item2

由于 JsonConvert.SerializeObject 在您分配可以在 您的 编译过程中使用的名称之前就已编译,因此它无法恢复这些名称。

方法 parameters/return 类型用 attributes 修饰,指示当方法的签名包含 ValueTuple 时要使用的名称。这允许稍后编写的代码通过编译器再次玩弄"see" 名称,但这就是 "wrong way around" 在这里很有用。

How to get the expected output

如果 fields/properties 的名称如此重要,请引入显式类型。

How to get the expected output

像这样:

var myTypes = new{ type = "A", text = "I am an animal"};
var cnvValue = JsonConvert.SerializeObject(myTypes);

如果您正在寻找类似的简洁方法,应该可以使用。尽管不使用 ValueTuples(但匿名类型);这是我将你的问题解释为“我如何在不完全声明 class 等的情况下产生这个预期的 JSON”

How to get the expected output

使用显式自定义类型或匿名 class 就像@Caius 的回答。

或者根本不为其创建特殊类型(对于匿名类型,编译器会在后台为您生成 class)并使用 JObject 动态创建 json:

var myTypesJson = new JObject(
    new JProperty("type", "A"), 
    new JProperty("text", "I am an animal")
);
var cnvValue = myTypesJson.ToString();

或者使用索引器和初始化syntax:

var createdJson = new JObject()
{
    ["type"] = "A",
    ["text"] = "I am an animal"
};
var cnvValue = createdJson.ToString();