gpt4 book ai didi

c# - 如何序列化可能只有唯一实例的类

转载 作者:太空宇宙 更新时间:2023-11-03 12:12:24 26 4
gpt4 key购买 nike

我有一个类只能有如下所示的唯一实例。这使得引用相等性足以等同于对象。

虽然序列化很简单,但反序列化有点棘手,因为不能像我在下面所做的那样分配给 this。如果仍然只想维护类的唯一实例,我该如何反序列化对象?

public sealed class MyClass :
ISerializable,
IXmlSerializable
{
private static readonly Dictionary<string, MyClass> Cache;

static MyClass() { /* build cache, use private constructor */ }

private MyClass(string name)
{
this.Name = name;
}

public string Name { get; }

public static MyClass Parse(string from)
=> Cache[from];

public void GetObjectData(SerializationInfo info, StreamingContext context)
=> throw new NotImplementedException();

public XmlSchema GetSchema() => null;

public void ReadXml(XmlReader reader)
{
reader.ReadStartElement();
this = Parse(reader.ReadContentAsString());
reader.ReadEndElement();
}

public MyClass(SerializationInfo info, StreamingContext context)
=> this = Parse(info.GetString(nameof(this.Name)));

public void WriteXml(XmlWriter writer)
=> throw new NotImplementedException();
}

最佳答案

一般来说,处理这个问题的方法是,在对象图序列化过程中,使用serialization surrogate mechanism替换单例。 ,其中单例被替换为 Data Transfer Object (DTO)它只包含单例的标识符。然后,稍后,随着图形被反序列化,DTO 最初被反序列化,然后通过查找替换为相应的单例。

例如,如果您的 MyClass 如下所示:

public sealed class MyClass
{
private static readonly Dictionary<string, MyClass> Cache;

static MyClass()
{
Cache = new Dictionary<string, MyClass>()
{
{ "one", new MyClass("one") { OtherRuntimeData = "other runtime data 1" } },
{ "two", new MyClass("two") { OtherRuntimeData = "other runtime data 2" } },
};
}

// XmlSerializer required parameterless constructor.
private MyClass() => throw new NotImplementedException();

private MyClass(string name) => this.Name = name;

public string Name { get; }

public string OtherRuntimeData { get; set; }

public static MyClass Parse(string from) => Cache[from];

public static IEnumerable<MyClass> Instances => Cache.Values;
}

那么只包含 Name 的 DTO 看起来像:

public sealed class MyClassDTO
{
public string Name { get; set; }

public static implicit operator MyClassDTO(MyClass obj) => obj == null ? null : new MyClassDTO { Name = obj.Name };

public static implicit operator MyClass(MyClassDTO dto) => dto == null ? null : MyClass.Parse(dto.Name);
}

注意 implicit operator在 DTO 和原始文件之间进行转换?这将使将代理项注入(inject)序列化图中变得更加容易。

不幸的是,没有标准的方法可以在所有常用的 .Net 序列化程序中实现序列化代理 DTO 的注入(inject)。每个都有自己独立的机制(或根本没有机制)。分解它们:

关于c# - 如何序列化可能只有唯一实例的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51467120/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com