2010-08-12 27 views
2

我有一個定義了只讀屬性的類,它實際上是對一個非常可變對象的引用,我想知道處理它的序列化是。處理C#中只讀字段的XML序列化

例如:

public class classA { 
    public readonly classB B = new classB(); 
} 

public class classB { 
    public string Name = "Test"; 
} 

這可以被序列化到(如果它是不是事實的「B」字段是隻讀的)

<classA> 
    <B> 
    <Name>Test</Name> 
    </B> 
</classA> 

但我不能反序列化,因爲序列化器會嘗試創建classB的新實例,並將classA上的字段設置爲該新對象。

如果我讓屬性不是隻讀的,這會打開客戶端代碼更改所使用的classB實例的可能性,這是不可接受的(許多其他對象在該實例上會有沉沒事件,因此它可以不會像這樣被替換)。或者,我可以讓setter將給定對象中的值複製到已存在的實例中,但這似乎過於繁瑣,以至於無法容納序列化程序。

我認爲有一個單獨的屬性與setter來處理序列化,並將其設置爲[Browsable(BrowsableState.Never)],但是這仍然暴露了將實例更改爲任何獲得反射靈巧的人的能力。

有沒有告訴序列化程序在反序列化中填充現有對象的方法,還是我將不得不創建自定義序列化程序?

+0

如果*反射*是有風險的,那麼所有的賭注都漂亮,多過已經... – 2010-08-12 22:25:04

+0

是啊,真的,我猜。我想沒有什麼能阻止某個人通過反射來改變私人領域。 – Flynn1179 2010-08-12 22:26:54

回答

3

好,IXmlSerializable選項,但它是不是一個理想之一;編寫一個不重要的強大實現是相當困難的。

如果有一個不變的屬性是重要,那麼也許考慮有一個單獨的DTO的實現 - 即一組簡單,可變類持久性,你翻譯成你的域實體。

或者,其他一些序列化器可能會有所幫助;例如,DataContractSerializer將在私人領域的工作:

[DataContract] 
public class classA { 
    [DataMember] 
    private classB b = new classB(); 

    public classB B { get {return b; } } 
} 
0

不幸的是,我無法看到使用自定義XML序列化程序來解決您的情況。但是,如果這是一個選項,我相信二進制序列化將在這種情況下工作。