在派生类

时间:2015-04-22 12:00:39

标签: c# xml deserialization

我正试图找到解决方案,但我不确定它是否可行。

我有一个基类,让我们说

public class A
{
   [XmlAttribute("Date")]
   public DateTime Date {get;set;}
}

和派生类:

public class B: A
{
   [XmlAttribute("Date")]
   public new String StringDate {get;set;}
}

我必须序列化一个Xml。

Xml上“Date”的值是String,实际上它不是DateTime格式字符串。但是我对许多其他东西使用“A”,所以我不能只将它改为String而不影响程序的其他部分。可悲的是,它不是一种选择。

所以我的想法是创建一个派生类“B”,它继承了“A”的所有内容并覆盖了属性Date,使其从反序列化中填充,然后将其格式化为DateTime。

我读过关于虚拟或摘要的内容,但我不熟悉它并且对此没有任何线索,如果是解决方案,也许有人可以在第一步指导我。

任何人都可以帮助我?

EDIT XML:

<Vorgang Vorgang="HQHT8GTQ">
        <Vertragsbeginn Vertragsbeginn="20140202" />
</Vorgang>

A类:

[DataContract(Name = "Vorgang")]
[KnownType(typeof(Vorgang))]
public class Vorgang
{
    [IgnoreDataMember]
    public DateTime Vertragsbeginn { get; set; }
}

B组:

public class VorgangOverride : UTILMD.Vorgang
{
    private string datestring;

    [XmlAttribute("Vertragsbeginn")]
    public new String Vertragsbeginn {
        get { return datestring; }
        set
        {
            base.Vertragsbeginn = DateUtil.StringToDate(value, EDIEnums.Vertragsbeginn);
            datestring = value;
        } 
    }
}

反序列化方法:

private static VorgangOverride Deserialize (XmlNode inVorgang)
{
    using (MemoryStream stm = new MemoryStream())
    {
        using (StreamWriter stw = new StreamWriter(stm))
        {
            stw.Write(inVorgang.OuterXml);
            stw.Flush();
            stm.Position = 0;

            XmlRootAttribute xRoot = new XmlRootAttribute { ElementName = "Vorgang", IsNullable = true };

            var serializer = new XmlSerializer(typeof(VorgangOverride), xRoot);

            VorgangOverride podItem = (VorgangOverride) serializer.Deserialize(stm);

            return podItem;
        }
    }
}

编辑: 解决了使用

[XmlRoot("Vorgang")]
public class VorgangOverride
{
    public VorgangOverride()
    {

    }
    #region Public Properties

    public string datestring;

    [XmlElement("Vertragsbeginn")]
    public Vertragsbeginn VertragsbeginnAsString { get ; set ;}

    #endregion
}

public class Vertragsbeginn
{

    [XmlAttribute("Vertragsbeginn")]
    public String vertragsbeginn { get; set; }
}

2 个答案:

答案 0 :(得分:1)

您将无法使用其他类类型覆盖属性。

原因是多态性。 (更多信息:https://msdn.microsoft.com/en-us/library/ms173152.aspx

您可以将类B转换为类A.这意味着类B必须具有类A所具有的所有属性和方法。但是在你的情况下,类B将有一个String而不是一个名为Date的Date。这根本不可能。

答案 1 :(得分:1)

我找到了解决方案:

[DataContract(Name = "Vorgang")]
[KnownType(typeof(Vorgang))]
public class Vorgang
{
    [XmlIgnore]  // use XmlIgnore instead IgnoreDataMember
    public DateTime Vertragsbeginn { get; set; }
}

// this class map all elements from the xml that you show
[XmlRoot("Vorgang")]  // to map the Xml Vorgang as a VorgangOverride instance
public class VorgangOverride : Vorgang
{
    [XmlAttribute("Vorgang2")]  // to map the Vorgang attribute
    public string VorgangAttribute { get; set; }

    [XmlElement(ElementName = "Vertragsbeginn")]  // to map the Vertragsbeginn element
    public Vertragsbeginn VertragsbeginnElement
    {
        get { return _vertragsbeginn; }
        set
        {
            base.Vertragsbeginn = new DateTime();  // here I Assing the correct value to the DateTime property on Vorgan class.
            _vertragsbeginn = value;
        }
    }
    private Vertragsbeginn _vertragsbeginn;
}

// this class is used to map the Vertragsbeginn element
public class Vertragsbeginn
{
    [XmlAttribute("Vertragsbeginn")]  // to map the Vertragsbeginn attriubute on the Vertragsbeginn element
    public string VertragsbeginnAttribute { get; set; }
}
后来我说:

var string xmlContent =
@"<Vorgang Vorgang2=""HQHT8GTQ"">
<Vertragsbeginn Vertragsbeginn=""20140202"" />
</Vorgang>";
        var a = Deserialize<VorgangOverride>(xmlContent);

这是反序列化的方法:

    // method used to deserialize an xml to object
    public static T Deserialize<T>(string xmlContent)
    {
        T result;
        var xmlSerializer = new XmlSerializer(typeof(T));
        using (TextReader textReader = new StringReader(xmlContent))
        {
            result = ((T)xmlSerializer.Deserialize(textReader));
        }
        return result;
    }