2009-12-24 40 views
0

我有一個f#庫,其中包含一些我想在c#中使用json序列化的值。 與寄存器我沒有問題,但我有錯誤,當我嘗試序列化代數數據類型。序列化f#代數數據類型

例如,可以說這是f#模塊,我想序列化t1。

module Module1= 

    type Tree = Leaf | Branch of Tree * int * Tree 

    let t1 = Leaf 

在C#我做了以下內容:

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Module1.Tree)); 
StreamWriter writer = new StreamWriter(@"c:\test"); 
serializer.WriteObject(writer.BaseStream, Module1.t1); 
writer.Close(); 

我有這個錯誤(在西班牙,因爲我的Visual Studio是西班牙語:S)

「沒有本質埃斯佩拉EL TIPO 'ns.Module1 + Tree + _Leaf'con el nombre de contrato de datos'Module1.Tree._Leaf:http://schemas.datacontract.org/2004/07/ns'。Agregue los tipos no conocidosestáticamentea la lista de tipos conocidos(por ejemplo,usando el atributo KnownTypeAttribute oagregándolosa la lista de tipos conocidos que se pasa a DataContractSerializer)。 「

我的翻譯: 「類型‘ns.Module1 +樹+ _leaf’是沒有預料到的數據合同名稱‘Module1.Tree._Leaf:http://schemas.datacontract.org/2004/07/ns’。靜態添加未知類型的已知類型的列表(例如,使用屬性KnownTypeAttribute或將它們添加到傳遞給DataContractSerializer的已知類型的列表中)。「

任何想法如何解決呢?

回答

3

問題是,從CLR的角度來看,t1引用的對象實際上並不是Module1.Tree類型,而是不相關的嵌套類型Module1.Tree+_Leaf。您需要通知DataContractJsonSerializer它可能遇到此類型的對象。希望在F#運行庫中有一個輔助方法來列出這樣的編譯器生成的嵌套類型;如果不是,你必須使用反射,例如

var serializer = new DataContractJsonSerializer (
    new List<Type> (typeof (Module1.Tree).GetNestedTypes()) { // nested types 
        typeof (Module1.Tree),      // root type 
    }.ToArray()) ; 

雖然我會有點害怕編寫這樣的代碼,除非F#實際上明確指定它是如何從代數類型生成CLR類型的。

+0

謝謝,這幫助我解決了那個特定的錯誤,現在我有了一個新的錯誤:P – hiena 2009-12-24 18:14:36

+2

或者您可以應用'[]'屬性來鍵入'Tree',如錯誤信息所示。 – 2009-12-24 18:29:24