2012-12-06 30 views
17

thể trùng lặp:
Why XML-Serializable class need a parameterless constructorTại sao tôi không thể tuần tự hóa một tuple trong C#?

Tôi đang cố gắng để serialize một tuple trong mã của tôi:

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(); 

nhưng nó đã thất bại và bắt ngoại lệ như thế này:

System.Tuple`2 [System.String, CodeExtractor.StatementNode] không thể được tuần tự hóa bởi vì nó không có một hàm tạo parameterless.

và tôi chắc chắn rằng CodeExtractor.StatementNode có thể được đăng.

+1

đọc báo cáo kết quả: _System.Tuple '2 [System.String, System.String] không thể được tuần tự hóa bởi vì nó không có một constructor parameterless_ ... nó khá rõ ràng! (xem decompilation: http://pastebin.com/b6vUMuX3) –

+0

CodeExtractor và StatementNode có thể tuần tự hóa được không? –

+0

xem câu hỏi này: http://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor – GolfWolf

Trả lời

2

Khi ngoại lệ cho bạn biết: Tuple<T1, T2> không có hàm tạo tham số NO nào cần thiết bởi trình nối tiếp.

22

Đối với XmlSerializer để có thể thực hiện công việc của nó, cần có một trình thu thập mặc định. Đó là một hàm tạo không có đối số. Tất cả các lớp Tuple < ...> đều có một hàm tạo duy nhất và hàm tạo đó nhận một số đối số. Một cho mỗi giá trị trong tuple. Vì vậy, trong trường hợp của bạn là nhà xây dựng duy nhất là

Tuple(T1 value1, T2 value2) 

Trình nối tiếp đang tìm kiếm một hàm tạo không có đối số và vì không tìm thấy nó, bạn sẽ có ngoại lệ.

bạn có thể tạo ra một lớp có thể thay đổi, mà có thể được thay thế cho các bộ với mục đích serialization

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); 
    } 
} 

Sau đó bạn có thể sử dụng nó theo cách sau

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

formatter.Serialize(fs, results.SelectMany(
           lst => lst.Select(
             t => (MyTuple)t 
            ).ToList() 
          ).ToList()); 
Các vấn đề liên quan