2010-02-26 20 views
5

Có thể deserialize các thuộc tính đối tượng, sử dụng bất kỳ serializers tiêu chuẩn, mà không cần tạo một đối tượng mới?Deserializing tài sản vào một đối tượng tồn tại từ trước

Vấn đề là, các đối tượng được đề cập rất phức tạp (chúng chỉ có thể được tạo bởi một nhà máy đặc biệt và loại của chúng được tạo động khi chạy), nhưng chúng có một số thuộc tính đã biết, mà tôi muốn lưu trữ ở bên ngoài tập tin (tốt hơn là xml, nhưng nhị phân là OK quá), và sau đó (có thể sau khi ứng dụng được khởi động lại), tôi muốn các thuộc tính được lưu trữ được đặt trở lại đối tượng mà tôi cung cấp. Có vẻ như tất cả các serializers tiêu chuẩn chỉ có thể tạo ra một đối tượng mới cho tôi (mà cũng đòi hỏi một constructor publiclessless), từ đó tôi sẽ phải gán tất cả các thuộc tính theo cách thủ công. Điều này không khác nhiều so với serialization thủ công, mà tôi muốn tránh, vì một tập hợp các thuộc tính tuần tự là khá lớn và có lẽ sẽ thay đổi một vài lần trong suốt thời gian tồn tại của dự án. Tại thời điểm này tôi khá gần với viết serializer của riêng tôi, nhưng có lẽ ai đó có thể đề xuất một cách tiêu chuẩn hơn để làm những việc như vậy?

Trả lời

3

protobuf-net có phương thức Serializer.Merge cho phép bạn deserialize vào một phiên bản hiện có. Chỉ các giá trị được tìm thấy trong luồng được ghi (nó không xóa đối tượng).

Không phải Microsoft, nhưng khá ổn định.

Để mở rộng điều này; nhận được serialization mạnh mẽ mà xử lý tất cả các kịch bản phổ biến là (tôi biết từ kinh nghiệm đau đớn) rất nhiều công việc. Đề nghị của tôi chắc chắn sẽ được tái sử dụng mã hiện tại nếu có thể. protobuf-net dường như cung cấp mọi thứ bạn cần; các tệp nhị phân hiện tại chỉ yêu cầu bạn trang trí lớp của bạn (rất giống với [DataContract] từ WCF - thực tế nó thậm chí còn hỗ trợ [DataContract]/[DataMember]), nhưng công việc được đặt ra để cho phép nó hoạt động ngay cả với POCO - vì vậy bạn có thể sử dụng nó với các loại bên ngoài kiểm soát của bạn.

+0

Điều đó không hoạt động ở cấp trường, thay vì cấp thuộc tính theo yêu cầu? – Lucero

+0

@Lucero - nó hoạt động trên cả hai lĩnh vực và thuộc tính; nó phụ thuộc vào những gì bạn bảo nó làm. –

+0

Cảm ơn bạn đã có một liên kết thú vị, nhưng tôi không muốn liên quan đến một thành phần bên thứ ba hoàn toàn mới cho một nhiệm vụ khá đơn giản như vậy. Ngoài ra, nhược điểm là nó không phải là xml. – Chriso

0

Bạn có thể triển khai "serializer" linh hoạt của riêng mình để xử lý việc này. Phản ánh cung cấp cho bạn mọi thứ bạn cần.

0

Bạn có thể sử dụng phương pháp FormatterServices.PopulateObjectMembers, mà dường như được thiết kế chính xác cho công việc này ...

+1

Đến thời điểm đó, bạn sẽ phải phân tích luồng để lấy các giá trị vào 'object' s, * và * thu được' MemberInfo' s, * và * xử lý tất cả các độ phức tạp của dữ liệu phụ, v.v.Thành thật mà nói, chỉ đơn giản là có một phương pháp để * set * các giá trị cung cấp ít - tại thời điểm đó bạn chỉ có thể sử dụng sự phản chiếu. –

2

Bạn có thể sử dụng FormatterServices lớp.

Bạn có một lớp Book:

[Serializable] 
class Book 
{ 
    public string Title { get; set; } 

    public string Author { get; set; } 

    // Constructor for setting new values. 
    public Book(string title, string author) 
    { 
     Title = title; 
     Author = author; 
    } 
} 

Bạn có thể serialize nó như thế này:

var book = new Book("Moby Dick", "Herman Melville"); 

string path = Path.GetTempFileName(); 

var bf = new BinaryFormatter(); 
using (var fs = new FileStream(path, FileMode.Create)) 
    bf.Serialize(fs, book); 

Nếu đối tượng của bạn được sửa đổi:

// Edit object 
book.Title = "Foo"; 
Console.WriteLine("{0}, {1}", book.Title, book.Author); 

Bạn có thể khôi phục lại nó với mã sau:

Book temp; 
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
    temp = (Book) bf.Deserialize(fs); 

MemberInfo[] members = FormatterServices.GetSerializableMembers(typeof (Book)); 
FormatterServices.PopulateObjectMembers(book, members, FormatterServices.GetObjectData(temp, members)); 

// Object state is back 
Console.WriteLine("{0}, {1}", book.Title, book.Author); 
Các vấn đề liên quan