添加另一個答案,因爲我對這個問題有一些樂趣。拿走或放棄它,但這可能是我如何攻擊這個功能。
這裏有一個更復雜的答案,但它使用泛型給你類型安全,大部分繁重的工作都在一個基類中完成(不需要複製/粘貼相同的代碼)。
增加一個屬性來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();
}
}
的「defalut的價值應該來自XML,而不是硬編碼。 – Codehelp
@Codehelp默認值是我們在沒有值存在時分配的值,如果我們從xml本身獲取值,那麼缺省值的用法是什麼? &你在OP中沒有提到過。請編輯您的問題,並更具體地說明您想要的解決方案。 – yogi
它明確提到'返回默認屬性值'。我想你在我的問題中的DefaultValue裝飾器和'默認'屬性標記之間混淆。 DefaultValue裝飾器硬編碼在這種情況下不起作用的實際值。希望這是明確的。 – Codehelp