C#DataContract序列化,如何反序列化到已经存在的实例 [英] C# DataContract Serialization, how to deserialize to already existing instance

查看:151
本文介绍了C#DataContract序列化,如何反序列化到已经存在的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,其中包含一个在编译时定义的所有现有实例的静态字典。

I have a class, which holds a static dictionary of all existing instances, which are defined at compile time.

基本上看起来像这样:

[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];
  }    

}

还有其他字段,类是派生的,但这与问题无关紧要。

There are other fields, and the class is derived, but this doesn't matter for the problem.

仅对 id 进行序列化。反序列化此类型的实例时,我想获取已创建为静态字段的实例( A B C ),使用 Foo.Get(id)而不是获取新实例。

Only the id is serialized. When an instance of this type is deserialized, I would like to get the instance that has been created as the static field (A, B or C), using Foo.Get(id) instead of getting a new instance.

有没有简单的方法可以做到这一点?我找不到我能理解的任何资源。

Is there a simple way to do this? I didn't find any resources which I was able to understand.

推荐答案

反序列化期间(AFAIK)始终使用一个新对象( FormatterServices.GetUninitializedObject ),但是要在反序列化之后(但在将它们返回给调用者之前)用它代替对象 IObjectReference ,就像这样:

During deserialization it (AFAIK) always uses a new object (FormatterServices.GetUninitializedObject), but to get it to substitute the objects after deserialization (but before they are returned to the caller), you can implement IObjectReference, like so:

[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上的部分信任方案,请此处

Note there are some extra notes on this for partial trust scenarios on MSDN, here.

这篇关于C#DataContract序列化,如何反序列化到已经存在的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆