2008-09-20 28 views

Trả lời

18

Trình XmlSerializer có một vài nhược điểm.

  1. Phải biết tất cả các loại được sắp xếp theo thứ tự. Bạn không thể vượt qua nó một cái gì đó bằng giao diện đại diện cho một loại mà serializer không biết.
  2. Nó không thể tham chiếu vòng tròn.
  3. Nó sẽ tuần tự hóa cùng một đối tượng nhiều lần nếu được tham chiếu nhiều lần trong biểu đồ đối tượng.
  4. Không thể xử lý tuần tự trường riêng.

Tôi (ngu ngốc) đã viết bộ nối tiếp của riêng mình để giải quyết một số vấn đề này. Đừng làm thế; nó là rất nhiều công việc và bạn sẽ tìm thấy lỗi tinh tế trong đó tháng xuống đường. Điều duy nhất tôi đạt được bằng văn bản serializer và định dạng của riêng tôi là một sự đánh giá cao hơn về minutia tham gia vào tuần tự hóa đồ thị đối tượng.

Tôi tìm thấy số NetDataContractSerializer khi WCF xuất hiện. Nó làm tất cả những thứ từ trên mà XmlSerializer không làm. Nó thúc đẩy việc tuần tự hóa theo cách tương tự với XmlSerializer. Một trang trí thuộc tính khác nhau hoặc các lĩnh vực với các thuộc tính để thông báo cho serializer những gì để serialize. Tôi thay thế serializer tùy chỉnh tôi đã viết với NetDataContractSerializer và đã rất hài lòng với kết quả. Tôi rất muốn khuyên bạn điêu đo.

+0

Tôi nghĩ rằng, với 3.5SP1 bạn thậm chí không cần phải trang trí với DataContract/DataMember nữa. –

+0

+1: NetDataContractSerializer - đó là một cái mới cho tôi. Cảm ơn! – x0n

2

Không chắc chắn nếu có bất kỳ giới hạn .. Nhưng có một lỗi rò rỉ bộ nhớ trong XmlSerialization trong .NET 1.1, bạn sắp phải tạo ra một đối tượng serializer bộ nhớ cache để có được xung quanh với vấn đề này ... Trong thực tế, Im không chắc chắn nếu sự cố này đã được khắc phục trong .net 2.0 hoặc mới hơn ...

+0

Tại sao một người nào đó downvote này? Các dịch vụ cửa sổ tôi đã viết đã bị mắc kẹt bởi rò rỉ bộ nhớ XMLSerializer này, và nó là tốt để lây lan từ IMHO. – Larry

1

Giới hạn mà tôi có thể nghĩ là XmlSerialization không tham gia; nghĩa là bất kỳ thuộc tính nào của một lớp mà bạn không muốn serialized phải được trang trí với [XmlIgnore]. Ngược lại với DataContractSerializer nơi tất cả các thuộc tính đều chọn tham gia, bạn phải khai báo rõ ràng các thuộc tính bao gồm. Đây là một số write-up tốt.

Hình ảnh hoặc mảng nhị phân của chúng được tuần tự hóa dưới dạng văn bản được mã hóa base64 bởi XmlSerializer.

1

Bất kỳ lớp nào bạn viết về mặt lý thuyết có thể được cấp thông qua XmlSerializer. Howerver, nó chỉ có quyền truy cập vào các trường công khai và các lớp cần phải được đánh dấu bằng các thuộc tính chính xác (ví dụ: XmlAttribute). Ngay cả trong khung cơ bản, không phải mọi thứ đều hỗ trợ XmlSerializer. Ví dụ: System.Collections.Generic.Dictionary <>.

1

Ví dụ: bạn không thể tuần tự hóa các lớp đang triển khai giao diện IDictionary.

0

Đối với bộ sưu tập, họ cần có phương thức Thêm để tham gia một đối số. Nếu bạn chỉ cần định dạng văn bản chứ không phải xml cụ thể, bạn có thể thử JSON. Tôi đã phát triển một cho .NET, JsonExSerializer và cũng có một số khác có sẵn tại http://www.json.org.

22

Tôi thường tìm thấy XmlSerializer là một lựa chọn không tốt cho bất kỳ POCO nào không chỉ là DTO. Nếu bạn yêu cầu XML cụ thể, bạn có thể đi thuộc tính Xml * và/hoặc IXmlSerializable - nhưng bạn bị bỏ lại với một đối tượng khá bị xáo trộn.

Vì một số mục đích, nó vẫn là lựa chọn hiển nhiên - ngay cả với những hạn chế của nó.Nhưng, chỉ đơn giản là lưu trữ và tải lại dữ liệu, tôi đã tìm thấy BinaryFormatter là một lựa chọn dễ dàng hơn nhiều với ít cạm bẫy hơn.

Dưới đây là danh sách một số phiền toái với XmlSerializer - nhất mà tôi đã cắn tại một thời điểm hay cách khác, những người khác tôi thấy qua tại MSDN:

  • Yêu cầu công cộng, không args constructor Chỉ
  • serializes công khai đọc/ghi thuộc tính và các lĩnh vực
  • Yêu cầu tất cả các loại được gọi là
  • Thực tế cuộc gọi vào get_ * và set_ *, do đó xác nhận, vv sẽ được chạy. Đây có thể là tốt hay xấu (suy nghĩ về thứ tự của các cuộc gọi cũng)
  • Sẽ chỉ serialize bộ sưu tập IEnumerable hoặc ICollection phù hợp với các quy định cụ thể

XmlSerializer cho đối xử đặc biệt đến các lớp học mà thực hiện IEnumerable hoặc ICollection. Một lớp thực hiện IEnumerable phải thực hiện một phương thức Add công cộng mà có một tham số đơn. Tham số của phương thức Add phải có cùng kiểu như được trả về từ thuộc tính Current trên giá trị được trả về từ GetEnumerator, hoặc một trong các căn cứ kiểu đó.

Một lớp thực hiện ICollection (chẳng hạn như CollectionBase) ngoài IEnumerable phải có thuộc tính được lập chỉ mục mục công khai (chỉ mục trong C#) có số nguyên và phải có thuộc tính Số công khai của số nguyên. Tham số cho phương thức Add phải là cùng kiểu như được trả về từ thuộc tính Item, hoặc một trong các căn cứ kiểu đó. Đối với các lớp thực hiện ICollection, các giá trị được tuần tự được lấy từ thuộc tính Item được lập chỉ mục, không phải bằng cách gọi hàm GetEnumerator.

  • Không serialize IDictionary
  • hội Sử dụng tự động tạo ra, mà có thể không được bốc dỡ từ các miền ứng dụng.

Để tăng hiệu suất, cơ sở hạ tầng tuần tự hóa XML tự động tạo các hội đồng để sắp xếp và loại bỏ các loại được chỉ định. Cơ sở hạ tầng tìm và tái sử dụng các hội đồng đó. Hành vi này chỉ xảy ra khi sử dụng các nhà thầu sau:

XmlSerializer.XmlSerializer (Type) XmlSerializer.XmlSerializer (Type, String)

Nếu bạn sử dụng bất kỳ các nhà thầu khác, nhiều phiên bản của cùng một assembly được tạo và không bao giờ được tải xuống, dẫn đến rò rỉ bộ nhớ và hiệu suất kém.

  • Không thể serialize ArrayList [X] hay Danh sách <T> []
  • Có trường hợp cạnh lạ khác

XmlSerializer không thể được khởi tạo để serialize một điều tra nếu các điều kiện sau true: Kiểu liệt kê có kiểu unsigned long (ulong in C#) và liệt kê chứa bất kỳ thành viên nào có giá trị lớn hơn 9.223.372.036.854.775.807.

Lớp XmlSerializer không còn nối tiếp các đối tượng được đánh dấu là [Lỗi thời].

Bạn phải có quyền ghi vào thư mục tạm thời (như được xác định bởi biến môi trường TEMP) để deserialize một đối tượng.

  • Yêu cầu đọc .InnerException nhận được bất kỳ thông tin hữu ích về các lỗi
+0

Jeez, đó là rất nhiều! giới hạn! Cảm ơn các chi tiết. Phiếu bầu +1 – Phil

3

vấn đề khác là kêu gọi các nhà xây dựng của XmlSerializer sẽ biên dịch mã trong thời gian chạy và sẽ tạo ra một DLL tạm thời (trong temp% % thư mục) với mã để thực hiện việc de/serialization.

Bạn có thể xem mã nếu bạn thêm dòng sau vào app.config:

<system.diagnostics> 
    <switches> 
     <add name="XmlSerialization.Compilation" value="4"/> 
    </switches> 
    </system.diagnostics> 

này mất rất nhiều thời gian lần đầu tiên bạn serialize một lớp và cần mã với quyền cho biên soạn và viết để đĩa.

Một cách để giải quyết vấn đề đó là biên dịch trước các DLL này bằng công cụ sGen.exe đi kèm với VS 2005+.

Look here for more information.

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