2016-12-22 63 views
1

如果我有標記的枚舉讓說的論據如何表示XML配置文件中的複合已標記的枚舉值

[Flags] 
public enum Shipping { Null=0x00, FedX=0x01, UPS=0x02, AirBrn=0x04, USPS=0x08, Any=0xFF} 

,我想保存在一個XML配置文件中該值,如

[XmlAttribute(AttributeName="shipper")] 
    public Shipping ShippingOption { get; set; } 

我知道,我必須組合值與空間,分隔例如,如果我想配置文件來表示ShippingOption爲任何FEDX或UPS,則XML是這樣的:

<ElementName shipper="FedX UPS" /> 

,或者如果我想它代表FEDX或UPS或USPS然後

<ElementName shipper="FedX UPS USPS" /> 

但是我放在屬性,如果我想它是什麼,但UPS? (假設枚舉不具備這一點) 預定值(如Shipping.Any這將是C#值相當於

 var ship = Shipping.Any & ^Shipping.UPS; 

我知道我可以只離開了一個我不想,這樣:?

<ElementName shipper="FedX USPS AirBrn " /> 

但如果有在得到乏味,(並且需要維修隨時隨地展開完整的列表)枚舉許多許多成員是否有手短的方式來表示一個標記的枚舉的否定

+0

僅供參考,它是[FedEx](http://www.fedex.com/us/) –

+0

哦,謝謝,這很有幫助。 –

+0

我將使用該標誌的複合「int」值並將其寫入爲屬性值。 – IAbstract

回答

1

這是一個相當簡單的解決方案,應該可以工作。首先,寫一個方法來解析您的自定義枚舉語法—在我的實現,~X手段「而不是X」:

private T ParseEnum<T>(string str) where T : struct, IConvertible 
{ 
    var result = 0; 
    foreach (var name in str.Split()) 
    { 
     if (name.StartsWith("~")) 
     { 
      result &= ~(int)(Enum.Parse(typeof(T), name.Substring(1), true)); 
     } 
     else 
     { 
      result |= (int)(Enum.Parse(typeof(T), name, true)); 
     } 
    } 

    return (T)(object)result; 
} 

這裏還有一個非常簡單的格式功能與原始的XML序列化兼容:

private string FormatEnum<T>(T s) where T : struct, IConvertible 
{ 
    return s.ToString().Replace(",", ""); 
} 

現在剛剛成立,無論你需要使用這個,並確保您標記的原始與XmlIgnore代理屬性:

[XmlIgnore] 
public Shipping ShippingOption { get; set; } 

[XmlAttribute(AttributeName = "shipper")] 
public string ShippingOptionString 
{ 
    get { return FormatEnum<Shipping>ShippingOption); } 
    set { ShippingOption = ParseEnum<Shipping>(value); } 
} 

現在將能夠正確解析XML是這樣的:對於不同的序列化圖書館存在

<ElementName shipper="Any ~UPS" /> 

其他解決方案,但該模式將基本上是相同的。將XML屬性反序列化爲字符串,然後使用自定義解析器解析它以獲得所需的枚舉結果。

+0

謝謝!這正是我需要的。我覺得有點傻,我沒有想到它自己,我使用這種技術來解決其他Xml序列化問題,只是沒有想到它!但這是我第一次聽說'代理財產'這個詞。 –