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 中的默认属性值。

问候。

4

4 回答 4

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; }

}

有关更多信息,请参阅

于 2013-01-21T06:02:06.463 回答
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();
    }
}
于 2013-01-21T08:45:43.267 回答
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; }

}
于 2013-01-21T06:10:44.603 回答
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 文件)

于 2013-01-21T07:22:33.493 回答