Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XML序列化具有隐藏继承成员的新属性的类_C#_Xml_Inheritance - Fatal编程技术网

C# XML序列化具有隐藏继承成员的新属性的类

C# XML序列化具有隐藏继承成员的新属性的类,c#,xml,inheritance,C#,Xml,Inheritance,我得到了以下抽象类的结构: 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 } 我在2003年遇到了一个问题

我得到了以下抽象类的结构:

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
}
我在2003年遇到了一个问题,这个问题的目的是给出一个答案,但我不确定如何实现这个修复(或者它是否在13年后有效)。它确实表明错误消息具有误导性,因为该消息提出的解决方案不起作用

如果我从Model.Template和类型化模型类中删除“set”访问器(例如,仅通过构造函数进行设置),则该类可以很好地序列化,尽管没有Template属性。有没有一种方法可以对隐藏(n)(抽象)基类属性的类进行XML序列化,而不必在每个继承的类上实现IXmlSerializable?

我遇到了david.woodward,它展示了一种处理这种情况的可行且实用的方法(即,当更改基类不是选项时)。它建议向
XmlSerializer
提供
XmlAttributeOverrides

使用您提供的对象模型,下面的代码演示了此方法的使用。它的工作原理是显式地告诉
XmlSerializer
忽略基类中的隐藏属性,在本例中是
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) { }
}
使用系统;
使用System.IO;
使用系统文本;
使用System.Xml.Serialization;
班级计划
{
静态void Main(字符串[]参数)
{
ConcreteTemplate ct=new ConcreteTemplate(){SomeProperty=“hello”};
ConcreteGenericModel cgm=新的ConcreteGenericModel(ct);
XmlAttributeOverrides attrOverides=新的XmlAttributeOverrides();
XmlAttributes attrs=newXMLAttributes(){XmlIgnore=true};
添加(typeof(Model),“Template”,attrs);
类型[]外部类型=新类型[0];
XmlSerializer serializer=新的XmlSerializer(typeof(ConcreteGenericModel)、属性、外部类型、null、null);
StringBuilder sb=新的StringBuilder();
使用(StringWriter=新StringWriter(sb))
serializer.Serialize(writer,cgm);
string serializedClass=sb.ToString();
Console.WriteLine(serializedClass);
ConcreteGenericModel反序列化DCGM;
使用(StringReader=新StringReader(serializedClass))
反序列化DCGM=(ConcreteGenericModel)序列化程序;
Console.ReadLine();
}
}
公共抽象类模板
{
//定义了一些属性和方法
公共虚拟字符串SomeProperty{get;set;}
}
公共抽象类模板:模板,其中TTemplate:Template
{
//未定义新属性,但重写了方法
}
公共类模板:模板{}
公共抽象类模型
{
公共模型(){}
公共模板模板{get;set;}
公共模型(模板t){Template=t;}
//更多属性和方法
}
公共类模型:模型
{
公共混凝土模型(模板t):基(t){}
}
公共抽象类模型:模型
其中TModel:Model
其中TTemplate:Template
{
公共模型(){}
公共新TTemplate模板{get{return(TTemplate)base.Template;}set{base.Template=value;}}
公共模型(TTemplate t):基(t){
//重写某些方法,但不重写新属性
}
公共类ConcreteGenericModel:模型
{
public-ConcreteGenericModel(){}
公共ConcreteGenericModel(ConcreteTemplate t):基(t){}
}

谢谢!虽然我通常将
extraTypes
传递给
XmlSerializer
构造函数,这意味着我还需要一个
XmlRoot
和默认名称空间,但看起来这是可行的。一切都序列化正常,只是现在反序列化有困难…您可以为不需要的
defaultNamespace
参数传递null。这是其他构造函数重载在内部执行的操作。我已经更新了示例以显示如何使用此重载。很抱歉,我遇到了一个旧问题,但是如果我同时需要对父类和子类进行序列化,会发生什么情况?可能必须为父类和子类分别显式控制/配置序列化。如果你有一个具体的例子,你能创建一个新的问题,引用这个问题,如果相关的话?
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.
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) { }
}