C# 我可以将属性应用于继承的成员吗?
假设我有以下(非常简单的)基类:C# 我可以将属性应用于继承的成员吗?,c#,xml-serialization,attributes,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("ob
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();
}
}
…不起作用。您是否可以使用重载
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" />
您可能知道这一点,但作为一种想法(尽管在这种情况下,代码结构将完全改变): 一种方法是使用自定义序列化将基类序列化为名称-值对的集合(还有XDocument和类似的有用的东西使其更简单)。虽然它不强制执行类型安全,但它可以使您免于执行大量手动工作
我还更喜欢自定义序列化,因为它允许更广泛的可能性(例如序列化不可变类)。XmlSerializer有时也很讨厌(例如,我讨厌添加“MyFieldSpecified”属性来创建可选属性)。也许您可以使用公共映射来标记基类属性,而不是只在继承类中重写该属性,因为它应该是不同的。至少你可以省下一些压倒一切的问题。我自己来回答这个问题,这样我就可以接受这个答案了。我不喜欢这个答案,但我想这是唯一有效的答案 答案是:不,你不能这样做 这个怎么样:
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)的相同技术。我认为您的意思是从Simple继承。这是否意味着单个xml文件可以同时包含和元素,哪些应该序列化为具有value属性的value类?显然,它们应该序列化为派生类,元素本身的名称取决于它的使用位置,但这是一般的想法。此外,在我的应用程序中,它更常用于写出XML而不是读入XML;我希望这会有所帮助。抱歉。虽然这可能有效,但它不允许我在派生类上指定重写。因此,对于属性名称不同的每个实例,我都应该有一个序列化程序,而所有这些不同的元素都可能出现在同一个文档中。这意味着我们有一个“域模型”和一个“xml模型”,这两个模型实际上是分开的。由于XmlSerializer的可定制性,我决定使用这种方法通过使用XmlWriter生成XML文件。我们的域模型是使用BinaryFormatter序列化的。您仍在重新定义属性。