XML使用新属性序列化类,该属性隐藏继承的成员 [英] XML serialize class with new property which hides inherited member

查看:119
本文介绍了XML使用新属性序列化类,该属性隐藏继承的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下抽象类的结构:

I've got the following structure of abstract classes:

public abstract class Template
{
   // Some properties and methods defined
}

public abstract class Template<TTemplate> : Template where TTemplate : Template
{
 // No new properties defined, but methods overriden
}

然后我将这些模板类用作模型的一部分:

I then use these template classes as part of a model:

public abstract class Model 
{
  public Template Template {get;set;}
  public Model(Template t) {Template = t;}
  // More properties and methods
}

public abstract class Model<TModel, TTemplate> : Model where TModel : Model where TTemplate : Template
{
  public new TTemplate template {get {return (TTemplate)base.Template;} set {base.Template = value;}}
  public Model(TTemplate t) : base(t) {}
  // Override some methods but no new properties
}

然后,我为模板和模型创建具体的类,并在我的项目中使用它们.这些具体类定义了除抽象基类中指定的属性以外的其他属性.我的问题是何时需要序列化Model类.我使用反射来查找所有继承的Model或Template类型,并将它们传递给XmlSerializer,以便它可以正确地序列化我的抽象类.但是,我有一个异常

I then create concrete classes of my template and models and use them in my project. These concrete classes define additional properties beyond those specified in the abstract base classes. My problem comes when it's time to serialize the Model classes. I use reflection to find all inherited types of Model or Template, and pass them into the XmlSerializer so it can properly serialize my abstract classes. However, I get an exception

There was an error reflecting type 'ConcreteModel'. ---> 
System.InvalidOperationException: There was an error reflecting property 
'Template'. ---> System.InvalidOperationException: Member 
ModelOfConcreteModelConcreteTemplate.Template of type ConcreteTemplate hides 
base class member Model.Template of type Template. Use XmlElementAttribute 
or XmlAttributeAttribute to specify a new name.

我在Google网上论坛上遇到这篇文章自2003年以来,它似乎给出了一个答案,但是我不确定如何实施该修补程序(或者是否在13年后仍然有效).它确实表明该错误消息具有误导性,因为该消息提出的解决方案不起作用.

I came across this post on google groups from 2003 which purports to give an answer, but I'm not sure how to implement that fix (or if it's even valid 13 years later). It does indicate that the error message is misleading as the solution proposed by the message does not work.

如果我从Model.Template中删除设置"访问器并键入Model类(例如,仅通过构造函数进行设置),则该类可以很好地进行序列化-尽管没有Template属性.是否可以通过XML序列化类来隐藏a(n)(抽象)基类的属性,而无需在每个继承的类上实现IXmlSerializable的方法呢?

If I remove the 'set' accessor from the Model.Template and typed Model classes (and just set it via the constructor, for example), the class serializes just fine - albeit without the Template property. Is there a way to XML serialize classes which hide properties from a(n) (abstract) base class, without implementing IXmlSerializable on every single inherited class?

推荐答案

我遇到了

I came across this post by david.woodward, showing a viable and on-the-rails method for dealing with this scenario (i.e. when changing the base class is not an option). It suggests providing XmlAttributeOverrides to the XmlSerializer.

使用提供的对象模型,以下代码说明了此方法的用法.它通过显式告诉XmlSerializer忽略基类(在本例中为Model.Template)中的隐藏属性来工作.

Using your provided object model, the following code illustrates the use of this. It works by explicitly telling the XmlSerializer to ignore the hidden property in the base class, in this case Model.Template.

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        ConcreteTemplate ct = new ConcreteTemplate() { SomeProperty = "hello" };
        ConcreteGenericModel cgm = new ConcreteGenericModel(ct);

        XmlAttributeOverrides attrOverides = new XmlAttributeOverrides();
        XmlAttributes attrs = new XmlAttributes() { XmlIgnore = true };
        attrOverides.Add(typeof(Model), "Template", attrs);

        Type[] extraTypes = new Type[0];
        XmlSerializer serializer = new XmlSerializer(typeof(ConcreteGenericModel), attrOverides, extraTypes, null, null);

        StringBuilder sb = new StringBuilder();
        using (StringWriter writer = new StringWriter(sb))
            serializer.Serialize(writer, cgm);
        string serializedClass = sb.ToString();

        Console.WriteLine(serializedClass);

        ConcreteGenericModel deserializedCgm;
        using (StringReader reader = new StringReader(serializedClass))
            deserializedCgm = (ConcreteGenericModel)serializer.Deserialize(reader);

        Console.ReadLine();
    }
}

public abstract class Template
{
    // Some properties and methods defined
    public virtual string SomeProperty { get; set; }
}

public abstract class Template<TTemplate> : Template where TTemplate : Template
{
    // No new properties defined, but methods overriden
}

public class ConcreteTemplate : Template { }

public abstract class Model
{
    public Model() { }
    public Template Template { get; set; }
    public Model(Template t) { Template = t; }
    // More properties and methods
}

public class ConcreteModel : Model
{
    public ConcreteModel(Template t) : base(t) { }
}

public abstract class Model<TModel, TTemplate> : Model
    where TModel : Model
    where TTemplate : Template
{
    public Model() { }
    public new TTemplate Template { get { return (TTemplate)base.Template; } set { base.Template = value; } }
    public Model(TTemplate t) : base(t) { }
    // Override some methods but no new properties
}

public class ConcreteGenericModel : Model<ConcreteModel, ConcreteTemplate>
{
    public ConcreteGenericModel() { }
    public ConcreteGenericModel(ConcreteTemplate t) : base(t) { }
}

这篇关于XML使用新属性序列化类,该属性隐藏继承的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆