ValueTuples序列化时会丢失其属性名称

时间:2019-01-28 08:20:47

标签: c# json.net tuples valuetuple

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

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

我期望序列化值为

  

{“ type”:“ A”,“ text”:“我是动物”}

但实际结果是

  

{“ Item1”:“ A”,“ Item2”:“我是动物”}

有两件事我很想知道

  • 为什么会这样
  • 如何获得预期的输出

3 个答案:

答案 0 :(得分:19)

  

如何获得预期的输出

类似这样的东西:

var myTypes = new{ type = "A", text = "I am an animal"};
var cnvValue = JsonConvert.SerializeObject(myTypes);
如果您正在寻找类似的简洁方法,

应该可以使用。不过不要在幕后使用ValueTuple(而是匿名类型);这是我将您的问题解释为“如何在不完全声明类的情况下如何生成此预期的JSON”

答案 1 :(得分:16)

名称是编译器的把戏。如果查看ValueTuple的定义,您会发现其字段名称仅为static void Main(string[] args) { ExecuteProcesses(new string[] { "test1.bat", "test2.bat", "test3.bat" }); } public static void ExecuteProcesses(string[] executablesPaths) { using (Process process = new Process()) { ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.RedirectStandardOutput = true; processStartInfo.UseShellExecute = false; process.StartInfo = processStartInfo; foreach (string executablePath in executablesPaths) { process.StartInfo.FileName = executablePath; process.Start(); Console.WriteLine(process.StandardOutput.ReadToEnd()); process.WaitForExit(); } } } Item1等。

由于Item2在分配给您在 编译期间可以使用的名称之前就已经进行了很好的编译,因此无法恢复名称。

方法参数/返回类型用attributes修饰,指示方法签名包含JsonConvert.SerializeObject时要使用的名称。这样一来,以后编写的代码就可以再次由编译器“玩弄”技巧,从而“看到”名称,但这就是在这里使用很多的“错误方法”。

  

如何获得预期的输出

如果字段/属性的名称非常重要,请引入显式类型。

答案 2 :(得分:0)

  

如何获得预期的输出

使用显式的自定义类型或匿名类,例如@Caius答案中的

或者根本不为其创建特殊类型(因为匿名类型编译器会在后台为您生成类),并使用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();