为属性分配默认值

时间:2013-01-21 05:51:48

标签: c#

我有一个像这样的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

如果标签User为空,

应该给“程序员”或xml中的默认属性值。

问候。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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();
    }
}

答案 2 :(得分: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; }

}

答案 3 :(得分: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文件)