2013-01-21 144 views
1

我有一個XML像這樣:分配默認值的屬性

<Settings> 
    <User default="Programmer"></User> 
    <Level default="2"></Level> 
<Settings> 

這是反序列化的類型UserSettings的對象:

[Serializable] 
[XmlRoot("Settings")] 
public class UserSettings 
{ 
    [XmlElement("User")] 
    public string User { get; set; } 

    [XmlElement("Level")] 
    public string Level { get; set; } 

} 

的UserSettings對象給出任何值是有在運行時爲標籤。

我希望類在標記爲空或標記在傳入xml中不存在時返回默認屬性值。

所以,如果有型UserSettings的對象objUserSettings然後

objUserSettings.User

應該給「程序員」,或無論是在默認屬性值在XML如果標籤的用戶是空的。

問候。

回答

1

添加另一個答案,因爲我對這個問題有一些樂趣。拿走或放棄它,但這可能是我如何攻擊這個功能。

這裏有一個更復雜的答案,但它使用泛型給你類型安全,大部分繁重的工作都在一個基類中完成(不需要複製/粘貼相同的代碼)。

增加一個屬性來UserSettings展現另一種類型的例子...

[Serializable] 
[XmlRoot("Settings")] 
public class UserSettings 
{ 
    public UserSettings() 
    { 
     User = new DefaultableStringValue(); 
     Level = new DefaultableIntegerValue(); 
     IsFullscreen = new DefaultableBooleanValue(); 
    } 

    [XmlElement("User")] 
    public DefaultableStringValue User { get; set; } 

    [XmlElement("Level")] 
    public DefaultableIntegerValue Level { get; set; } 

    [XmlElement("IsFullscreen")] 
    public DefaultableBooleanValue IsFullscreen { get; set; } 
} 

類型DefaultableValues的簡單實現...

[Serializable] 
public class DefaultableStringValue : DefaultableValue<string> 
{ 
    public DefaultableStringValue() : base(s => s) { } 
} 

[Serializable] 
public class DefaultableIntegerValue : DefaultableValue<int> 
{ 
    public DefaultableIntegerValue() : base(int.Parse) { } 
} 

[Serializable] 
public class DefaultableBooleanValue : DefaultableValue<bool> 
{ 
    public DefaultableBooleanValue() : base(bool.Parse) { } 
} 

基類,做所有繁重的解析和緩存解析值...

[Serializable] 
public abstract class DefaultableValue<T> 
{ 
    protected Func<string, T> _parsingFunc; 

    private string _valueText; 
    private T _cachedValue; 
    private bool _isValueCached; 

    private string _defaultText; 
    private T _cachedDefault; 
    private bool _isDefaultCached; 

    protected DefaultableValue(Func<string, T> parsingFunc) 
    { 
     _parsingFunc = parsingFunc; 
     _isValueCached = false; 
     _isDefaultCached = false; 
    } 

    [XmlAttribute("default")] 
    public string DefaultText 
    { 
     get { return _defaultText; } 
     set 
     { 
      _defaultText = value; 
      _isDefaultCached = false; 
     } 
    } 

    [XmlText] 
    public string ValueText 
    { 
     get { return _valueText; } 
     set 
     { 
      _valueText = value; 
      _isValueCached = false; 
     } 
    } 

    [XmlIgnore] 
    public T Default 
    { 
     get 
     { 
      if (_isDefaultCached) 
       return _cachedDefault; 

      if (HasDefault) 
       return ParseAndCacheValue(DefaultText, out _cachedDefault, out _isDefaultCached); 

      return default(T); 
     } 
     set 
     { 
      DefaultText = value.ToString(); 
      _cachedDefault = value; 
      _isDefaultCached = true; 
     } 
    } 

    [XmlIgnore] 
    public T Value 
    { 
     get 
     { 
      if (_isValueCached) 
       return _cachedValue; 

      if (HasValue) 
       return ParseAndCacheValue(ValueText, out _cachedValue, out _isValueCached); 

      return Default; 
     } 
     set 
     { 
      ValueText = value.ToString(); 
      _cachedValue = value; 
      _isValueCached = true; 
     } 
    } 

    [XmlIgnore] 
    public bool HasDefault { get { return !string.IsNullOrEmpty(_defaultText); } } 

    [XmlIgnore] 
    public bool HasValue { get { return !string.IsNullOrEmpty(_valueText); } } 

    private T ParseAndCacheValue(string text, out T cache, out bool isCached) 
    { 
     cache = _parsingFunc(text); 
     isCached = true; 

     return cache; 
    } 
} 

和樣本程序來演示使用...

public class Program 
{ 
    private static void Main(string[] args) 
    { 
     UserSettings userSettings = new UserSettings(); 
     userSettings.User.Default = "Programmer"; 
     userSettings.Level.Default = 2; 
     userSettings.Level.Value = 99; 

     XmlSerializer xmlSerializer = new XmlSerializer(typeof(UserSettings)); 

     string serializedUserSettings; 
     using (StringWriter stringWriter = new StringWriter()) 
     { 
      xmlSerializer.Serialize(stringWriter, userSettings); 
      serializedUserSettings = stringWriter.GetStringBuilder().ToString(); 
     } 

     UserSettings deserializedUserSettings; 
     using (StringReader stringReader = new StringReader(serializedUserSettings)) 
     { 
      deserializedUserSettings = (UserSettings)xmlSerializer.Deserialize(stringReader); 
     } 

     Console.Out.WriteLine("User: HasDefault={0}, Default={1}, HasValue={2}, Value={3}", 
      deserializedUserSettings.User.HasDefault ? "Yes" : "No", 
      deserializedUserSettings.User.Default, 
      deserializedUserSettings.User.HasValue ? "Yes" : "No", 
      deserializedUserSettings.User.Value); 

     Console.Out.WriteLine("Level: HasDefault={0}, Default={1}, HasValue={2}, Value={3}", 
      deserializedUserSettings.Level.HasDefault ? "Yes" : "No", 
      deserializedUserSettings.Level.Default, 
      deserializedUserSettings.Level.HasValue ? "Yes" : "No", 
      deserializedUserSettings.Level.Value); 

     Console.Out.WriteLine("IsFullscreen: HasDefault={0}, Default={1}, HasValue={2}, Value={3}", 
      deserializedUserSettings.IsFullscreen.HasDefault ? "Yes" : "No", 
      deserializedUserSettings.IsFullscreen.Default, 
      deserializedUserSettings.IsFullscreen.HasValue ? "Yes" : "No", 
      deserializedUserSettings.IsFullscreen.Value); 

     Console.ReadLine(); 
    } 
} 
1

試試這個

using System.ComponentModel; 

[Serializable] 
[XmlRoot("Settings")] 
public class UserSettings 
{ 
    [DefaultValue("Yogesh")] 
    [XmlElement("User")] 
    public string User { get; set; } 

    [DefaultValue("1st")] 
    [XmlElement("Level")] 
    public string Level { get; set; } 

} 

欲瞭解更多信息請參閱this

+0

的「defalut的價值應該來自XML,而不是硬編碼。 – Codehelp

+0

@Codehelp默認值是我們在沒有值存在時分配的值,如果我們從xml本身獲取值,那麼缺省值的用法是什麼? &你在OP中沒有提到過。請編輯您的問題,並更具體地說明您想要的解決方案。 – yogi

+0

它明確提到'返回默認屬性值'。我想你在我的問題中的DefaultValue裝飾器和'默認'屬性標記之間混淆。 DefaultValue裝飾器硬編碼在這種情況下不起作用的實際值。希望這是明確的。 – Codehelp

0

您可以使用屬性的默認值屬性。

在你情況下,它將,

[Serializable] 
[XmlRoot("Settings")] 
public class UserSettings 
{ 
    [XmlElement("User")] 
    [DefaultValue("Programmer")] 
    public string User { get; set; } 

    [XmlElement("Level")] 
    [DefaultValue(2)] 
    public string Level { get; set; } 

} 
0

我不相信有一種方法來告訴字符串使用默認XML屬性。您必須將這些對象中的每一個反序列化爲具有默認值的結構,作爲xml屬性的屬性。

下面是一個例子...

[Serializable] 
[XmlRoot("Settings")] 
public class UserSettings 
{ 
    [XmlElement("User")] 
    public DefaultableValue User { get; set; } 

    [XmlElement("Level")] 
    public DefaultableValue Level { get; set; } 

} 

[Serializable] 
public class DefaultableValue 
{ 
    [XmlAttribute("default")] 
    public string Default { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

而且樣本程序來演示使用...

public class Program 
{ 
    private static void Main(string[] args) 
    { 
     UserSettings userSettings = new UserSettings(); 
     userSettings.User = new DefaultableValue() 
      { 
       Default = "Programmer", 
       Value = "Tyler" 
      }; 
     userSettings.Level = new DefaultableValue() 
      { 
       Default = "2", 
       Value = "99" 
      }; 

     XmlSerializer xmlSerializer = new XmlSerializer(typeof(UserSettings)); 

     string serializedUserSettings; 
     using (StringWriter stringWriter = new StringWriter()) 
     { 
      xmlSerializer.Serialize(stringWriter, userSettings); 
      serializedUserSettings = stringWriter.GetStringBuilder().ToString(); 
     } 

     UserSettings deserializedUserSettings; 
     using (StringReader stringReader = new StringReader(serializedUserSettings)) 
     { 
      deserializedUserSettings = (UserSettings)xmlSerializer.Deserialize(stringReader); 
     } 

     Console.Out.WriteLine("User: Default={0}, Actual={1}", 
      deserializedUserSettings.User.Default, 
      deserializedUserSettings.User.Value); 

     Console.Out.WriteLine("Level: Default={0}, Actual={1}", 
      deserializedUserSettings.Level.Default, 
      deserializedUserSettings.Level.Value); 
    } 
} 

(請注意,我在代碼中的默認值,但他們很好可以有來自xml文件)