为所有“new”序列化基类实现属性

本文关键字:序列化 基类 实现 属性 new | 更新日期: 2023-09-27 18:13:52

我有一堆从XSD自动生成的类,并以编译后的DLL提供给我,但我没有源代码。我需要为每个类型添加接口,这导致了如下代码:

public interface IBar
{
    string SomeProperty { get; set; }
}
public interface IFoo<TBar> where TBar : IBar
{
    TBar Bar { get; set; }
}
public class BarWrapper : BarFromXSD, IBar
{
}
public class FooWrapper : FooFromXSD, IFoo<BarWrapper>
{
    [XmlElement("bar")]
    public new BarWrapper Bar
    {
        get { return base.Bar as BarWrapper; }
        set { base.Bar = value; }
    }
}

如果客户端给我一个DLL,其中任何底层类型的接口发生了变化,我将得到编译时错误告诉我。但是,如果底层DLL中的序列化属性发生变化,则不成立。在这种情况下,我的包装器类将愉快地序列化成与关联的xsd不兼容的对象。

上面代码的另一个问题是它根本不起作用。当我尝试为类型为FooWrapper的对象创建XmlSerializer时,我得到了异常链:

显示类型为"mynamspace . foowrapper"的错误。
反映属性"Bar"出错。
FooWrapper成员。类型为MyNamespace的栏。BarWrapper隐藏基类成员cs_Foo。dllnamespaces .Bar类型的Bar。使用XmlElementAttribute或xmllattributeattribute指定新名称。

为了避免这个问题,我想用更简单的方法:

1)覆盖默认序列化,以忽略"new"属性实现,或者
2)反射性地将所有XML序列化属性从基类复制到派生类

我试图用任何可能的解决方案来解决的问题是:

1)我想在静态构造函数中执行一次反射,以确定序列化的元素/属性名称和名称空间。
2)我有多个类遵循与FooWrapper相同的模式,因此任何解决方案都应该适用于任何此类类。
3)遵循FooWrapper模式的类可以包含在基类中未定义的需要序列化的其他属性。
4)理想的解决方案应该优雅地处理新属性。例如,如果以后我添加或删除一个"new"属性,我不应该添加/删除其他方法,或者必须在静态构造函数中硬编码"new"属性的名称。

任何满足这些要求的解决方案的见解都是非常感谢的。

为所有“new”序列化基类实现属性

这是一个非常简单的xml继承的例子。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication51
{
    class Program
    {
        const string FILENAME = @"c:'temp'test.xml";
        static void Main(string[] args)
        {
            Root root = new Root() {
                bar = new Bar1() {
                    foo = "123"
                }
            };

            XmlSerializer serializer = new XmlSerializer(typeof(Root));
            StreamWriter writer = new StreamWriter(FILENAME);
            XmlSerializerNamespaces _ns = new XmlSerializerNamespaces();
            _ns.Add("", "");
            serializer.Serialize(writer, root, _ns);
            writer.Flush();
            writer.Close();
            writer.Dispose();
        }
    }
    [XmlRoot("Root")]
    public class Root 
    {
        public Bar bar {get;set;}
    }
    [XmlInclude(typeof(Bar1))]
    [XmlRoot("Bar")]
    public class Bar 
    {
    }
    [XmlRoot("Bar1")]
    public class Bar1 : Bar
    {
        [XmlElement("foo")]
        public string foo {get;set;}
    }
}

看XML。添加了一个'type'属性

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <bar d2p1:type="Bar1" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance">
    <foo>123</foo>
  </bar>
</Root>