2009-12-24 4 views
0

У меня есть библиотека f # с некоторыми значениями, которые я хочу сериализовать в C# с помощью json. С регистрами у меня не было проблем, но у меня возникают ошибки, когда я пытаюсь сериализовать алгебраические типы данных.Serialize 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(); 

Я имеющий эту ошибку (на испанском языке, потому что моя визуальная студия не на испанском языке: S)

«Нет С.Е. Espera типо эль '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 conocidos estáticamente a la lista de tipos conocidos (por ejemplo, usando el atributo KnownTypeAttribute o agregándolos a 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

+2

Или вы можете применить атрибут '[]', чтобы напечатать 'Tree', как намечено сообщение об ошибке. –

Смежные вопросы