2012-01-23 15 views
11

tôi đã này:XMLSERIALIZE một Enum Cờ lĩnh vực

[Flags] 
    public enum InfoAbonne{civilite,name,firstname,email,adress,country } 

    public class Formulaire 
    { 
     private InfoAbonne _infoAbonne{ get; set;} 
     public Formulaire() 
     {} 
    } 

Tôi muốn XML serialize Formulaire

Nếu tôi init:
_infoAbonne = InfoAbonne.name | InfoAbonne.email;

Trong Result Xml của tôi, tôi chỉ nhận được:

<InfoAbonne>email</InfoAbonne> 

Trả lời

14

Mặc dù bạn thêm thuộc tính Flags để enum của bạn, bạn vẫn cần phải đảm bảo rằng các giá trị là quyền hạn của hai:

[Flags] 
public enum InfoAbonne 
{ 
    civilite = 1, 
    name = 2, 
    firstname = 4, 
    email = 8, 
    adress = 16, 
    country = 32 
} 

Xem hướng dẫn đặt ra trong chú phần của thứ e documentation.

+1

Ok nó hoạt động nhưng bình thường tôi nhận được email dân sự hai giá trị của tôi có khoảng trống giữa? –

+0

+1 để đơn giản và tham khảo MSDN. Mặc dù tỷ lệ upvotes 11: 1 từ câu trả lời của bạn là một chút nhiều! Không bao giờ;) –

+0

@ Dr.AndrewBurnett-Thompson: Đồng ý. Lý do cho điều này có thể là bạn đặt trọng tâm của bạn vào phần tuần tự hóa và chỉ sau đó đã thêm phần giải quyết vấn đề cơ bản. –

7

Ý tưởng cơ bản với các loại o này f vấn đề là để serialize một lĩnh vực sao lưu bắt chước các lĩnh vực bạn muốn serialize. Cùng nguyên tắc có thể được áp dụng cho các loại phức tạp như Bitmaps vv ... Ví dụ, thay vì serializing lĩnh vực Enum trực tiếp, bạn có thể serialize một lĩnh vực sao lưu kiểu int:

// Disclaimer: Untested code, both in execution and compilation 
[Flags]  
public enum InfoAbonne 
{ 
    civilite = 0x1, // Increment each flag value by *2 so they dont conflict 
    Name=0x2, 
    firstname=0x4, 
    email=0x8, 
    adress=0x10, 
    country=0x20 
} 

// Don't serialize this field 
[XmlIgnore] 
private InfoAbonne _infoAbonne { get; set;} 

// Instead serialize this field as integer 
// e.g. name | email will equal 0xA in hex, or 10 in dec 
[XmlElement("InfoAbonne")] 
private InfoAbonneSerializer 
{ 
    get { return (int)_infoAbonne; } 
    set { _infoAbonne= (InfoAbonne) value; } 
} 

Trân trọng,

+0

Tôi không hiểu tại sao bạn sử dụng InfoAbonneSerializer. Tôi không muốn giá trị int. –

+0

@ChristopheDebove Xin chào! Trường Serializer bao bọc trường thực tế bạn muốn hiển thị trong đối tượng miền của bạn, cho phép nó được sắp xếp tuần tự một cách chính xác. Nó không thực sự quan trọng những gì giá trị là trong tập tin XML, miễn là nó vẫn tồn tại và có thể được tải lại. –

+0

Andrew Burnett-Thompson ok, nhưng tôi không cần phải deserialize nhưng tôi sử dụng nó để chuyển đổi xslt vì vậy enum "văn bản" giá trị là interresting nhiều hơn cho tôi. Nhưng Cảm ơn bạn –

0

Câu trả lời của bác sĩ ABT tốt hơn câu trả lời đã chọn. Có, có giá trị trong quyền hạn của 2 là cần thiết, nhưng đó không phải là cụ thể cho các vấn đề XML serialization.

Enums được tuần tự hóa rất khác so với hầu hết các đối tượng. Enums sẽ được XML Serialized theo tên của chúng (ser(MyEnumProperty.[Name]) = "[Name]") thay vì sử dụng giá trị của tên (ser(MyEnumProperty.[Name]) = 8).

// Version 1.0 
[Flags]  
public enum MyEnum 
{ 
    None = 0, 
    First = 1, 
    Second = 2, 
    All = First | Second 
} 

public MyEnum MyEnumProperty = MyEnum.All; 

Nếu bạn đã serialize MyEnumProperty, bạn sẽ nhận được <MyEnum>All</MyEnum>. Tuy nhiên, nếu bạn đã tuần tự hóa (int)MyEnumProperty, bạn sẽ nhận được <int>3</int>. Tôi muốn đề cập đến lý do tại sao điều này là cực kỳ cần thiết để biết ...

// Version 2.0 
[Flags]  
public enum MyEnum 
{ 
    None = 0, 
    First = 1, 
    Second = 2, 
    Third = 4, // <--- 
    All = First | Second | Third 
} 

Tôi đã thêm giá trị Enum mới, có thể đã được sử dụng (dưới dạng DLL) trong các dự án khác. Oh wow ... những lỗi này là gì?

Bạn không còn có thể deserialize phiên bản mới nhất của enum thành phiên bản cũ hơn với XML Serialization (Binary Serialization vẫn hoạt động)!

Hãy xem phương pháp ToEnum của Microsoft. Điều này ngăn chặn một ID (nói, "thứ ba" trong enum cập nhật) từ được xem xét bởi vì nó không tồn tại trong enum ban đầu. Cũng lưu ý rằng một lỗi sẽ được ném mà có thể phá vỡ dự án của bạn nếu nó không được xử lý.

Hãy an toàn, luôn luôn tuần tự hóa và deserialize theo giá trị khi có cơ hội. Đây là lý do tại sao chúng tôi sử dụng các đối tượng như các enum được gắn cờ để bắt đầu. Các đối tượng như enum được gắn cờ làm giảm các vấn đề tương thích và phụ thuộc ngược.

0
[Flags] 
public enum InfoAbonne 
{ 
    civilite = (1 << 0), 
    name = (1 << 1), 
    firstname = (1 << 2), 
    email = (1 << 3), 
    adress = (1 << 4), 
    country = (1 << 5) 
} 
+2

Chào mừng bạn đến với Stack Overflow. Vui lòng xem xét thêm một chút giải thích về cách giải quyết câu hỏi của OP. –