序列化f#代数数据类型

时间:2009-12-24 14:20:08

标签: c# serialization f#

我有一个带有一些值的f#库,我希望用cson在c#中序列化。 使用寄存器我没有问题但是当我尝试序列化代数数据类型时我遇到了错误。

例如,假设这是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();

我有这个错误(西班牙语,因为我的视觉工作室是西班牙语:S)

“No se espera el tipo'ns.Module1 + Tree + _Leaf'con el nombre de contrato de datos'Module1Tree._Leaf:http://schemas.datacontract.org/2004/07/ns'。Agregue los tipos noconocidosestáticamenteala lista de tipos conocidos(por ejemplo,usando el atributo KnownTypeAttributeoagregándolosala lista de tipos conocidos que se pasa a DataContractSerializer)。“

我的翻译: “数据合约名称'Module1.Tree._Leaf:http://schemas.datacontract.org/2004/07/ns'不需要类型'ns.Module1 + Tree + _Leaf'。将未知类型静态添加到已知类型列表中(例如,使用属性KnownTypeAttribute或将它们添加到传递给DataContractSerializer的已知类型列表中。“

任何想法如何解决?

1 个答案:

答案 0 :(得分: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类型。