2015-05-04 44 views
2

我使用DataContract序列化程序来序列化我的数据。我使用PreserveObjectReferences = true,因为我需要它。 我有例如两个对象:DataContractSerializer - 将字符串序列化为值而不是引用

[Datacontract] 
class A 
{ 
    [DataMember] string _name; 
    ... 
    public A(string name) 
    { 
    _name = name; 
    } 
} 

[Datacontract] 
class B 
{ 
    [DataMember] string _name; 
    ... 
    public B(string name) 
    { 
    _name = name; 
    } 
} 

两者都有_name场。 然后,我创建了一个实例和B,其中我的第二个对象从对象的名称相同的名称使用:

var obj1 = new A("John"); 
var obj2 = new B(obj1.Name); 

然后我序列化和XML包含:

... 
<d11p1:_name z:Id="505">John</d11p1:_name> 
.. 
<d11p1:_name z:Ref="505" i:nil="true" /> 

所以第二个对象的字段_name被序列化为引用而不是Value。

然后我不需要对象A,所以我删除它。但我希望能够打开一个包含A类数据的旧保存文件,但在我的程序的新版本中,我不再需要类A了。

问题是DataContractSerializer不能反序列化B的实例,因为它的_name是对未反序列化(类被删除)的_name的引用。

有什么办法可以强制DataContractSerializer将字符串序列化为值类型而不是引用?

我知道一种解决方案不是删除A类,而是包含很多在我的程序的新版本中不重要的数据。

+0

序列化对象是B您已经创建了新的类?你可以修改B类吗? – danish

+0

不是班级B也是旧版本的程序。正如我所写的那样,它被序列化为XML文件。它在新版本的程序中是必需的。新版本的程序必须读取旧程序保存的文件。 B类的变化是什么意思? – Philipe

+0

我的意思是如果可以对B类中的代码进行更改。由于您已经指示序列化程序来保存引用,它将会。 – danish

回答

1

不幸的是,这是PreserveObjectReferences的工作方式。

您可以试试[DataContract(IsReference = true)]而不是PreserveObjectReferences。它仅适用于参考类型。

其中包含列表

<M1 z:Id="i2"> 
    <name>name1</name> 
</M1> 
<M2 z:Id="i3"> 
    <name>name1</name> 
</M2> 
<M3 z:Ref="i3"/> 
<list> 
    <m2 z:Ref="i3"/> 
    <m2 z:Id="i4"> 
     <name i:nil="true"/> 
    </m2> 
</list> 
+0

所以你的意思是不要为所有对象使用PreserveObjectReferences,而只能为我自己的类使用PreserveObjectReferences。所以字符串将被排除。但是像其他系统引用像数组呢?我有我的数据树(我整个序列化)由大约50个类组成,一些类可以共享相同的数组。所以,如果我只为我的类使用PreserveObjectReferences,那么examle数组将作为两个不同的实例创建。 – Philipe

+0

如果您的数组包含参考类型,则它将显示为仅参考。 (post edited) – sac1

+0

我的意思是例如两个具有相同数组的对象:
class M1 { Person [] _list; public M1(Person [] list) { _list = list; } } 和相同的类M2和我将创建它们与相同的数组(参考) – Philipe

相关问题