2013-05-05 26 views
9

Đến với mạng protobuf, tuyệt vời! Tôi có một câu hỏi liên quan đến việc tuần tự hóa các danh sách trống.Danh sách rỗng của Protobuf-Net

tôi bắt đầu bằng cách tuyên bố đối tượng tôi muốn serialize:

[ProtoContract] 
class TestClass 
{ 
    [ProtoMember(1)] 
    List<int> _listOfInts = new List<int>(); 

    public TestClass() { } 

    public List<int> ListOfInts 
    { 
     get { return _listOfInts; } 
     set { _listOfInts = value; } 
    } 
} 

Nếu _listOfInts trống (nhưng không phải null) khi tôi deserialse đối tượng này là sẽ luôn luôn là null. Điều này làm cho cảm giác nhìn vào ước protobuf và tôi hiện đang làm việc xung quanh này bằng cách thêm các phương pháp sau đây:

[ProtoAfterDeserialization] 
private void OnDeserialize() 
{ 
    if (_listOfInts == null) 
     _listOfInts = new List<int>(); 
} 

Câu hỏi của tôi là liệu tôi có thể đạt được chức năng này tương tự một cách ngắn gọn hơn, có thể với một attirbute bổ sung mà sẽ khởi tạo các đối tượng rỗng/rỗng dưới dạng rỗng thay vì null?

Trả lời

5

Nếu bạn đang cố gắng bảo vệ chống lại danh sách trống, bạn có thể thử tải chậm trong bộ nạp tài sản.

public List<int> ListOfInts 
{ 
    get { return _listOfInts ?? (_listOfInts = new List<int>()); } 
    set { _listOfInts = value; } 
} 

Bằng cách này bạn chỉ có thể cho phép trình nối tiếp trả về giá trị rỗng.

+0

Đây là một khả năng tôi đã không xem xét, sẽ bỏ phiếu cho bạn nếu tôi có thể. Tôi vẫn chủ yếu quan tâm để biết nếu có một thuộc tính mà sẽ làm điều này cho tôi mặc dù. – CanCan

+0

Bạn đã thử thuộc tính [DefaultValue] chưa? Không chắc chắn nếu bạn có thể khởi tạo danh sách nhưng đáng để thử. – Jras

+0

@ Jras Tôi đã xem xét việc thêm như vậy, nhưng mỗi khi tôi đã xem xét nó, nó quay ra để thực sự làm cho mã của người dân tồi tệ hơn, không tốt hơn –

6

Có một vấn đề cơ bản ở đây về cách protobuf mã hóa dữ liệu: danh sách chính nó không xuất hiện trong dữ liệu - chỉ các phần tử. Bởi vì điều này, chỉ đơn giản là không rõ ràng để lưu trữ thông tin về danh sách. Nó có thể được giả mạo bằng cách gửi một Boolean bằng cách sử dụng serialization có điều kiện, nhưng thẳng thắn mà là một chút hacky và xấu xí - và cho biết thêm phức tạp. Cá nhân, tôi khuyên bạn nên trừu tượng ra khỏi danh sách có thể là rỗng. Ví dụ:

private readonly List<Foo> items = new List<Foo>(); 
[ProtoMember(1)] 
public List<Foo> Items { get { return items; } } 

Hoặc

private List<Foo> items; 
[ProtoMember(1)] 
public List<Foo> Items { get { return items ?? (items = new List<Foo>()); } } 

Và lưu ý rằng lời khuyên này không chỉ là về serialization: đó là về tránh tùy ý null-tham khảo-ngoại lệ. Mọi người thường không mong đợi các bộ sưu tập phụ là rỗng.

+0

Có lý do gì khiến bạn không khởi tạo bộ sưu tập trên trường mục riêng tư không? Tôi có thể thấy rằng nếu bạn không truy cập vào getter của thuộc tính Items bạn không treo vào một tham chiếu bộ sưu tập rỗng, nhưng bạn đang trả giá của một kiểm tra null mỗi lần. Nó chỉ là tình huống? – Shaun

Các vấn đề liên quan