2012-12-06 10 views
17

Powiel możliwe:
Why XML-Serializable class need a parameterless constructorDlaczego nie można serializować krotki w języku C#?

Próbuję serializacji krotki z mojego kodu:

List<List<Tuple<String, CodeExtractor.StatementNode>>> results = null; 
results = extractor.ExtractSourceCode(sourceCode); 
FileStream fs = new FileStream(@"C:\Projects\Test\ast.xml", FileMode.Create); 

XmlSerializer formatter = new XmlSerializer(
    typeof(List<List<Tuple<String, CodeExtractor.StatementNode>>>)); 

formatter.Serialize(fs, results); 

fs.Close(); 

ale nie powiodło się i złapać wyjątek takiego:

System.Tuple`2 [System.String, CodeExtractor.StatementNode] nie może zostać szeregowany, ponieważ nie ma konstruktora bez parametrów.

i jestem pewien, że CodeExtractor.StatementNode może być serializowany.

+1

przeczytać oświadczenie: _System.Tuple '2 [System.String, System.String] nie może być serializowany, ponieważ nie ma konstruktora bez parametrów ... jest całkiem jasne! (patrz dekompilacja: http://pastebin.com/b6vUMuX3) –

+0

Czy CodeExtractor i StatementNode są serializowane? –

+0

zobacz to pytanie: http://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor – GolfWolf

Odpowiedz

2

Jako wyjątek mówi: Tuple<T1, T2> ma NO konstruktora bez parametrów, które jest potrzebne przez serializer.

22

Dla XmlSerializer, aby móc wykonywać swoją pracę, potrzebuje domyślnego contruktora. To jest konstruktor, który nie przyjmuje argumentów. Wszystkie klasy Tuple < ...> mają jeden konstruktor, a ten konstruktor pobiera szereg argumentów. Jeden dla każdej wartości w krotce. Więc w twoim przypadku jedynym konstruktorem jest

Tuple(T1 value1, T2 value2) 

serializer poszukuje konstruktora bez argumentów i dlatego, że nie może go znaleźć, pojawi się wyjątek.

można utworzyć klasę zmienny, który może być zastąpiony przez krotki dla celów serializacji

class MyTuple<T1, T2> 
{ 
    MyTuple() { } 

    public T1 Item1 { get; set; } 
    public T2 Item2 { get; set; } 

    public static implicit operator MyTuple<T1, T2>(Tuple<T1, T2> t) 
    { 
     return new MyTuple<T1, T2>(){ 
         Item1 = t.Item1, 
         Item2 = t.Item2 
        }; 
    } 

    public static implicit operator Tuple<T1, T2>(MyTuple<T1, T2> t) 
    { 
     return Tuple.Create(t.Item1, t.Item2); 
    } 
} 

Można następnie używać go w następujący sposób

XmlSerializer formatter = new XmlSerializer(
    typeof(List<List<MyTuple<String, CodeExtractor.StatementNode>>>)); 

formatter.Serialize(fs, results.SelectMany(
           lst => lst.Select(
             t => (MyTuple)t 
            ).ToList() 
          ).ToList()); 
Powiązane problemy