【问题标题】:What is the best way to serialize circular referenced objects?序列化循环引用对象的最佳方法是什么?
【发布时间】:2011-09-25 10:42:07
【问题描述】:

最好是文本格式。最好的是 json,带有一些标准的指针。二进制也很好。请记住,在过去,肥皂对此有标准。你有什么建议?

【问题讨论】:

  • 请澄清问题并添加更多信息:那么,您想要文本格式还是二进制格式?为什么说 JSON 是最好的?你为什么要序列化图表?尺寸有多重要?您是否需要从另一种语言访问序列化数据?图表看起来如何?就不能用不包含循环引用的方式序列化,在反序列化的时候恢复吗?
  • @TMB 是的,标准是正确的。这是某些语言中的常见错误,例如德语。
  • YAML 可以很好地处理引用。您可能想要使用它。
  • @Mark 好的,谢谢,我不知道。

标签: c# json serialization


【解决方案1】:

binary 没问题:

[Serializable]
public class CircularTest
{
    public CircularTest[] Children { get; set; }
}

class Program
{
    static void Main()
    {
        var circularTest = new CircularTest();
        circularTest.Children = new[] { circularTest };
        var formatter = new BinaryFormatter();
        using (var stream = File.Create("serialized.bin"))
        {
            formatter.Serialize(stream, circularTest);
        }

        using (var stream = File.OpenRead("serialized.bin"))
        {
            circularTest = (CircularTest)formatter.Deserialize(stream);
        }
    }
}

DataContractSerializer 也可以处理循环引用,你只需要使用一个特殊的构造函数并指出这一点,它就会吐出 XML:

public class CircularTest
{
    public CircularTest[] Children { get; set; }
}

class Program
{
    static void Main()
    {
        var circularTest = new CircularTest();
        circularTest.Children = new[] { circularTest };
        var serializer = new DataContractSerializer(
            circularTest.GetType(), 
            null, 
            100, 
            false, 
            true, // <!-- that's the important bit and indicates circular references
            null
        );
        serializer.WriteObject(Console.OpenStandardOutput(), circularTest);
    }
}

最新版本的Json.NET 也支持循环引用以及 JSON:

public class CircularTest
{
    public CircularTest[] Children { get; set; }
}

class Program
{
    static void Main()
    {
        var circularTest = new CircularTest();
        circularTest.Children = new[] { circularTest };
        var settings = new JsonSerializerSettings 
        { 
            PreserveReferencesHandling = PreserveReferencesHandling.Objects 
        };
        var json = JsonConvert.SerializeObject(circularTest, Formatting.Indented, settings);
        Console.WriteLine(json);
    }
}

产生:

{
  "$id": "1",
  "Children": [
    {
      "$ref": "1"
    }
  ]
}

我猜这就是你要问的。

【讨论】:

    猜你喜欢
    • 2012-03-31
    • 2010-09-27
    • 1970-01-01
    • 2021-10-24
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多