簡體   English   中英

為所有“新”屬性序列化基類實現

[英]Serialize Base Class Implementation for all “new” Properties

我有一堆類是從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 ,出現異常鏈:

反映類型'MyNamespace.FooWrapper'的錯誤。
反映屬性“ Bar”的錯誤。
MyNamespace.BarWrapper類型的成員FooWrapper.Bar隱藏了DLLNamespace.Bar類型的基類成員cs_Foo.Bar。 使用XmlElementAttribute或XmlAttributeAttribute指定新名稱。

為了避免這個問題,我想做一個簡單的方法:

1)覆蓋默認序列化,以忽略“新”屬性的實現,或者
2)反射性地將所有XML序列化屬性從基類復制到派生類

我嘗試使用任何潛在解決方案解決的問題是:

1)我想在靜態構造函數中執行一次反射,以確定序列化的元素/屬性名稱和名稱空間。
2)我有多個類遵循與FooWrapper相同的模式,因此任何解決方案都應適用於任何此類。
3)遵循FooWrapper模式的類可以包含其他需要序列化的未在基類中定義的屬性。
4)理想的解決方案應優雅地處理新屬性。 例如,如果以后我添加或刪除“ 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。 添加了“類型”屬性。

<?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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM