55

I am curious about how the Tuple<T1, T2, T3, ...> serializes and deserializes. I searched using keywords "json" and "tuple" but I could not find what I want.

4

4 回答 4

53

我通过Json.netUnitTest进行测试,测试代码如下。结果表明是可序列化和可反序列化的。所以我可以在我的应用程序中使用它们。Tuple<T1,T2,T3,...>

测试代码

public class Foo {
    public List<Tuple<string, string, bool>> Items { get; set; }

    public Foo()
    {
        Items = new List<Tuple<string, string, bool>>();
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        foreach (var a in Items)
        {
            sb.Append(a.Item1 + ", " + a.Item2 + ", " + a.Item3.ToString() + "\r\n");
        }
        return sb.ToString();
    }
}

[TestClass]
public class NormalTests
{
    [TestMethod]
    public void TupleSerialization()
    {
        Foo tests = new Foo();
        
        tests.Items.Add(Tuple.Create("one", "hehe", true));
        tests.Items.Add(Tuple.Create("two", "hoho", false));
        tests.Items.Add(Tuple.Create("three", "ohoh", true));

        string json = JsonConvert.SerializeObject(tests);
        Console.WriteLine(json);

        var obj = JsonConvert.DeserializeObject<Foo>(json);
        string objStr = obj.ToString();
        Console.WriteLine(objStr);
    }
}

概括

  • Tuple.Create("own","hehe",true)序列化为 {"Item1":"one","Item2":"hehe","Item3":true}

  • {"Item1":"one","Item2":"hehe","Item3":true}可以反序列化回Tuple<string,string, bool>

  • Class FooTuple数据,可以序列化为json字符串,字符串可以反序列化回Class Foo.

于 2013-04-19T09:10:55.227 回答
27

如果您正在寻找一个简短的答案。我正在使用JsonConvert

var testTuple = Tuple.Create(1234, "foo", true);
var serialized = JsonConvert.SerializeObject(testTuple);

Console.WriteLine(serialized);
// prints: {"Item1":1234,"Item2":"foo","Item3":true}

我做了一个最小的小提琴

于 2018-07-19T07:45:15.153 回答
7

对于 .NET5 和很快的 .NET6,现在建议System.Text.Json在 NewtonSoft 上使用。这个序列化器关于元组的重要事情是设置JsonSerializerOptions选项IncludeFields,否则默认情况下会排除元组值。

此外,命名元组只是语法糖Item1Item2由编译器替换为标准符号。要包含名称,最简单的方法是使用匿名对象

下面是一个最小的例子。(可以使用 .NET5 编译器粘贴到.NET fiddle中)


using System;
using System.Collections.Generic;
using System.Text.Json;
                    
public class Program
{
    public static void Main()
    {
        JsonSerializerOptions options = new() { IncludeFields = true };

        var testTuple = ("test" , "test1", 1324, false);
        var serializedTuple = JsonSerializer.Serialize(testTuple, options);
        Console.WriteLine(serializedTuple);
        
        var testTuple2 = (NamedItem1: "test" , NamedItemTwo: "test1", TheIntegersName: 1324, ThisBoolHasAFirstNameIts: false);
        var serializedTuple2 = JsonSerializer.Serialize(new {testTuple2.NamedItem1, testTuple2.NamedItemTwo, testTuple2.TheIntegersName, testTuple2.ThisBoolHasAFirstNameIts }, options);
        Console.WriteLine(serializedTuple2);
        
    }
}

输出:

{"Item1":"test","Item2":"test1","Item3":1324,"Item4":false}

{"NamedItem1":"test","NamedItemTwo":"test1","TheIntegersName":1324,"ThisBoolHasAFirstNameIts":false}

于 2021-10-21T16:33:44.917 回答
1

感谢 Hinrich 到上面的 dotnetfiddle 链接。

我使用了相同的链接,并了解了转换如何在 Json 对象和元组之间工作。下面是代码:

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class Program
{
    public static void Main()
    {

        var testTuple = Tuple.Create<int, string, bool>(1234, "foo", true);
        var serialized = JsonConvert.SerializeObject(testTuple);
        Console.WriteLine(serialized);
        JObject test = ((JObject)JsonConvert.DeserializeObject(serialized));
        string strSerialized = JsonConvert.SerializeObject(test);
        //Tuple<int, string, bool> testTuple1 = JsonConvert.DeserializeObject<Tuple<int, string, bool>>(serialized); // WORKs
        Tuple<int, string, bool> testTuple1 = JsonConvert.DeserializeObject<Tuple<int, string, bool>>(strSerialized); // WORKs
        Console.WriteLine(testTuple1.Item1.ToString());
    }
}

希望有人觉得这很有帮助。

于 2020-05-08T10:53:53.820 回答