我有一个类,它包含所有现有实例的静态字典,这些实例是在编译时定义的。
基本上它看起来像这样:
[DataContract]
class Foo
{
private static Dictionary<long, Foo> instances = new Dictionary<long, Foo>();
[DataMember]
private long id;
public static readonly Foo A = Create(1);
public static readonly Foo B = Create(2);
public static readonly Foo C = Create(3);
private static Foo Create(long id)
{
Foo instance = new Foo();
instance.id = id;
instances.Add(instance);
return instance;
}
public static Foo Get(long id)
{
return instances[id];
}
}
还有其他字段,类是派生的,但这对问题来说无关紧要。
只有 id
被序列化。当这个类型的实例被反序列化时,我想得到已经创建为静态字段的实例(A
,B
或C
),使用 Foo.Get(id)
而不是获取新实例。
有没有简单的方法来做到这一点?我没有找到任何我能够理解的资源。
最佳答案
在反序列化过程中,它 (AFAIK) 总是使用一个新对象 (FormatterServices.GetUninitializedObject
),但要让它替换反序列化之后的对象(但在它们返回之前)给调用者),你可以实现 IObjectReference
,像这样:
[DataContract]
class Foo : IObjectReference { // <===== implement an extra interface
object IObjectReference.GetRealObject(StreamingContext ctx) {
return Get(id);
}
...snip
}
完成...证明:
static class Program {
static void Main() {
Foo foo = Foo.Get(2), clone;
DataContractSerializer ser = new DataContractSerializer(typeof(Foo));
using (MemoryStream ms = new MemoryStream()) { // clone it via DCS
ser.WriteObject(ms, foo);
ms.Position = 0;
clone = (Foo)ser.ReadObject(ms);
}
Console.WriteLine(ReferenceEquals(foo, clone)); // true
}
}
请注意,在 MSDN 上有一些关于部分信任场景的额外说明,here .
关于C# DataContract 序列化,如何反序列化到已经存在的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1941580/