我可以将属性应用于继承的成员吗?

时间:2009-06-24 11:44:13

标签: c# xml-serialization attributes

假设我有以下(简单的简单)基类:

public class Simple
{
    public string Value { get; set; }
}

我现在想要做以下事情:

public class PathValue : Simple
{
    [XmlAttribute("path")]
    public string Value { get; set; }
}

public class ObjectValue : Simple
{
    [XmlAttribute("object")]
    public string Value { get; set; }
}

但实际上没有重新定义财产。我想将属性应用于基类的成员。这可能吗?

真正的问题在于我的序列化机制从/到XML(它的工作非常出色),我发现很多类似的元素,只有属性的名称不同(它们不一致,我不控制格式)。现在我需要为每个这样的元素创建一个不同的类,而它们就像100%相同(除了属性)。

我认为这不可能,但你可能永远不会知道。

更新:

我尝试过Marc的方法,但无济于事:

public class Document
{
    public PathValue Path;
    public ObjectValue Object;
}

class Program
{
    static void Main(string[] args)
    {
        var doc = new Document()
        {
            Path = new PathValue() { Value = "some path" },
            Object = new ObjectValue() { Value = "some object" }
        };

        XmlAttributeOverrides overrides = new XmlAttributeOverrides();

        overrides.Add(typeof(PathValue), "Value", new XmlAttributes() { XmlAttribute = new XmlAttributeAttribute("path") });
        overrides.Add(typeof(ObjectValue), "Value", new XmlAttributes() { XmlAttribute = new XmlAttributeAttribute("object") });

        XmlSerializer serializer = new XmlSerializer(typeof(Document), overrides);

        serializer.Serialize(Console.Out, doc);

        Console.WriteLine();
        Console.ReadLine();
    }
}

......没有做到这一点。

5 个答案:

答案 0 :(得分:4)

我将自己回答这个问题,以便接受这个答案。我不喜欢这个答案,但我认为这是唯一有效的答案。

答案是:不,你不能这样做。

答案 1 :(得分:2)

您是否可以使用重载XmlSerializer构造函数来传递要在运行时应用的属性?那你就不用担心了......

警告:您希望缓存序列化程序实例并重新使用它;否则(使用复杂的构造函数)它每次都会生成动态类型。

示例:

using System;
using System.Xml.Serialization;
public class Simple {
    public string Value { get; set; }

    static void Main() {
        XmlAttributeOverrides overrides = new XmlAttributeOverrides();
        overrides.Add(typeof(Simple), "Value", new XmlAttributes {
           XmlAttribute = new XmlAttributeAttribute("path")
        });
        XmlSerializer pathSerializer = new XmlSerializer(
            typeof(Simple), overrides);
        // cache and re-use pathSerializer!!!

        Simple obj = new Simple();
        obj.Value = "abc";
        pathSerializer.Serialize(Console.Out, obj);
    }
}

输出:

<Simple xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" path="abc" />

答案 2 :(得分:1)

这个怎么样:

public class Simple
{
    [XmlIgnore]
    public string Value { get; set; }
}

public class PathValue : Simple
{
    [XmlAttribute("path")]
    public string Path { 
            get { return base.Value != null ? base.Value : null; }
            set { base.Value = value != null ? value : null; }
    }
}

public class ObjectValue : Simple
{
    [XmlAttribute("object")]
    public string Object { 
            get { return base.Value != null ? base.Value : null; }
            set { base.Value = value != null ? value : null; }
    }
}

这与用于序列化不可序列化类型的技术相同,如Uri,它在构造函数中采用可序列化类型。

答案 3 :(得分:0)

您可能已经意识到这一点,但作为一个想法(虽然在这种情况下代码结构会完全改变):

一种方法是使用自定义序列化将基类序列化为名称 - 值对的集合(还有XDocument和类似的有用的东西,以使其更容易)。虽然它不会强制实施类型安全,但它可以避免您进行大量的手工操作。

我也更喜欢自定义序列化,因为它允许更广泛的可能性(例如,序列化不可变类)。 XmlSerializer有时候也很讨厌(例如我讨厌添加“MyFieldSpecified”属性来创建可选属性)。

答案 4 :(得分:0)

也许您可以使用公共映射标记基类属性,而不是仅覆盖继承类中应该不同的属性。至少你会节省一些压倒一切。