Tại sao các thuộc tính không có bộ định thời không được tuần tự hóa


100

Tôi có một lớp có thể tuần tự hóa và một trong những thuộc tính trong lớp của tôi tạo ra một Guidtrong getter. Thuộc tính thực hiện không có setter và bị bỏ qua trong quá trình tuần tự hóa. Tại sao lại như vậy và tôi có phải luôn triển khai một bộ định tuyến để tài sản của tôi được tuần tự hóa không.

[Serializable]
public class Example
{
    [XmlAttribute("id")]
    public string Id
    {
        get
        {
             return Guid.NewGuid().ToString();
        }
    }
}

Tôi đã thử triển khai một setter trống và nó đã được tuần tự hóa chính xác.

[Serializable]
public class Example
{
    [XmlAttribute("id")]
    public string Id
    {
        get
        {
             return Guid.NewGuid().ToString();
        }
        set {}
    }
}

Cập nhật :

Bạn có thể chỉ ra cách tôi nên xác định các thuộc tính có giá trị không bao giờ thay đổi hoặc các thuộc tính mà giá trị cho được tạo nội bộ không?


1
Ví dụ thứ hai tuần tự hóa chính xác ... Nhưng điều gì sẽ xảy ra khi bạn cố gắng giải mã hóa nó?
LightStriker

Hãy thử YAXLib [+ , + ]
Sina Iravanian

3
FYI, Trình sắp xếp thứ tự XML bỏ qua [Serializable].
John Saunders

@JohnSaunders Tôi không biết về điều đó.
Konstantin Dinev

Câu trả lời:


59

Đó là một hạn chế của XmlSerializernó không tuần tự hóa các thuộc tính chỉ đọc, những gì bạn đã làm trong ví dụ thứ hai của mình về cơ bản là hack để khiến nó tuần tự hóa, tuy nhiên, sẽ vô ích nếu bạn cần nó để giải mã hóa sau này.

Ngoài ra, bạn có thể chuyển sang sử dụng DataContractSerializer , nó linh hoạt hơn.


8
DataContractSerializer cũng yêu cầu bộ định tuyến. Đây là một hạn chế vì mặc dù chúng ta có thể chỉ sử dụng nó cho một loại hoạt động, chẳng hạn như deserialization, nhưng các khai báo cần phải cho cả hai, nếu không, quá trình tuần tự hóa sẽ không biết phải làm gì với một giá trị khi nó đang cố gắng tuần tự hóa một XML thành các đối tượng.
ryadavilli

7
@ryadavilli bất kỳ thứ gì được đánh dấu là [DataMember]được tuần tự hóa bằng cách sử dụng DataContractSerializer(chỉ đọc hoặc không).
James

1
@James Tôi đã viết ở trên vì tôi gặp một số lỗi thời gian biên dịch khi tôi thử tương tự. Bây giờ, khi tôi quay lại mã của mình và xóa bộ cài đặt, nó có vẻ như đang biên dịch tốt. Đây là bài tập rất hay và có lẽ là bài tập về nhà để tôi nghiên cứu thêm về điều này.
ryadavilli

3
Ahhh cuối cùng đã tìm ra nguồn gốc của sự bối rối của tôi. Không cần thiết lập thuộc tính để tuần tự hóa. Tuy nhiên, nếu một thuộc tính không có bộ thiết lập, thì XML sẽ không giải mã cho một đối tượng. Ở đó, bài tập về nhà đã hoàn thành.
ryadavilli

1
@ryadavilli yep chính xác, đó chỉ là một hạn chế của việc XmlSerializertriển khai, nó dựa vào phương thức setter công khai. DataContractSerializertheo nghĩa đó thì thông minh hơn một chút (có thể là sử dụng sự phản chiếu để thiết lập trường đằng sau hậu trường).
James

10

Xem " Giới thiệu về tuần tự hóa XML " trong tài liệu MSDN. Trong số những thứ khác, nó nói:

Các mục có thể được xếp theo thứ tự

Các mục sau có thể được tuần tự hóa bằng cách sử dụng lớp XmlSerializer:

Public read/write properties and fields of public classes.

Classes that implement ICollection or IEnumerable.

Ghi chú:

Only collections are serialized, not public properties.
XmlElement objects.

XmlNode objects.

DataSet objects.

Ngoài ra, hãy xem " Tại sao lớp XML-Serializable cần một hàm tạo không tham số "


Ngoài ra, IXmlSerializable

Ngoài các kiểu trên có thể được tuần tự hóa bởi XML Serializer, bất kỳ kiểu nào triển khai giao diện IXmlSerializable đều có thể được tuần tự hóa và giải mã hóa. Đặc biệt, điều này có nghĩa là các loại XElement và XDocument có thể được đăng nhiều kỳ.

Xem " Giao diện IXmlSerializable ".


6

Giới hạn của XMLSerializer- Các thuộc tính không có setter không thể được tuần tự hóa.

Nhưng bạn có thể sử dụng DataContractSerializerđể tuần tự hóa private setter properties-

[DataMember]
public string Id
{
    get
    {
         return Guid.NewGuid().ToString();
    }
    private set {}
}

Thuộc tính phải được tuần tự hóa thành thuộc tính xml (xem bài đăng gốc). Mã của bạn (thuộc tính DataMember) tạo ra một phần tử xml. Theo như tôi biết thì không có cách nào (rõ ràng) để yêu cầu DataContractSerializer biến một thuộc tính thành một thuộc tính chứ không phải một phần tử. DataContractSerializer rất hay nhưng bạn luôn phải ghi nhớ hạn chế này.
sth_Weird 10/02/16

2

nếu bạn muốn có các bộ cài đặt riêng tư và đối tượng có thể tuần tự hóa / có thể giải thích được, có thể điều khiển được impliment và tạo một phương thức khởi tạo như MyObject (thông tin SerializationInfo, ngữ cảnh StreamingContext). Một ví dụ được tìm thấy ở đây .


0

Thuộc tính tuần tự hóa được sử dụng để tuần tự hóa và giải mã hóa các đối tượng. XmlSerializer sẽ giả định rằng bạn không cần phải tuần tự hóa bất kỳ thuộc tính nào không có bộ định tuyến. Setter sẽ được sử dụng khi giải mã hóa một chuỗi thành một đối tượng, vì một thể hiện của đối tượng cần được tạo và sau đó setter sẽ được sử dụng để điền giá trị thuộc tính.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.