2009-12-24 89 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