在派生 class 上将 属性 覆盖为另一种类型

Override a property to another type on derived class

我正在尝试为此找到解决方案,但不确定是否可行。

我有一个基础class,假设

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

和派生的 class:

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

我必须序列化一个Xml。

Xml 上的 "Date" 的值是字符串,实际上它不是 DateTime 格式的字符串。但是我将 "A" 用于许多其他内容,因此我不能在不影响程序其他部分的情况下将其更改为 String。遗憾的是,这不是一个选择。

所以我的想法是创建一个派生的 class "B" 继承 "A" 的所有内容并覆盖 属性 日期以从反序列化中填充它然后将其格式化为 DateTime。

我阅读了有关 virtual 或 abstracts 的内容,但我不熟悉它,也没有任何线索,如果它是解决方案,也许有人可以指导我迈出第一步。

谁能帮帮我?

编辑 XML:

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

Class答:

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

Class乙:

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; }
}

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

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

您可以将 class B 转换为 class A。这意味着 class B 也必须具有 class A 具有的所有属性和方法。但在您的情况下 class B 将有一个字符串而不是一个名为 Date 的日期。这根本不可能。

我找到了解决方案:

[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;
    }