使用C#将xml反序列化为超类对象

使用C#将xml反序列化为超类对象,第1张

概述我正在创建一个程序,允许用户使用基本 *** 作定义公式:使用 XML进行加,减,除,多.让我们举一个例子:用户想要定义像(a b)x(c d)这样的公式. xml的格式如下: 编辑我实现了这一点 编辑解决.非常感谢Yaniv的建议.我的解决方案如下: <xPlugins> <xPlugin> <Multiple> <Add> <Operator> 我正在创建一个程序,允许用户使用基本 *** 作定义公式:使用 XML进行加,减,除,多.让我们举一个例子:用户想要定义像(a b)x(c d)这样的公式. xml的格式如下:

编辑我实现了这一点

编辑解决.非常感谢Yaniv的建议.我的解决方案如下:

<xPlugins>  <xPlugin>    <Multiple>      <Add>        <Operator>          <value>1</value>        </Operator>        <Operator>          <value>2</value>        </Operator>      </Add>      <Add>        <Operator>          <value>3</value>        </Operator>        <Operator>          <value>4</value>        </Operator>      </Add>    </Multiple>  </xPlugin></xPlugins>

//root elementpublic class xPlugins{    [XmlElement("xPlugin",typeof(xPlugin))]    public xPlugin[] Plugin { get; set; }}public class xPlugin{    [XmlElement("Multiple",typeof(Multiple))]    [XmlElement("Add",typeof(Add))]    [XmlElement("Subtract",typeof(divIDe))]    [XmlElement("divIDe",typeof(divIDe))]    [XmlElement("Operator",typeof(Operand))]    public Calculator calculator { get; set; }        }//Deseirialize ultilitystatic class readxml{            public static voID getobject(ref xPlugins plugins)    {        try        {            List<Type> type = new List<Type>();            type.Add(typeof(Add));            type.Add(typeof(Minus));            type.Add(typeof(Multiple));            type.Add(typeof(Subtract));            type.Add(typeof(Operator));            XmlSerializer xml = new XmlSerializer(typeof(xPlugin),type.ToArray());            fileStream fs = new fileStream("test.xml",fileMode.Open);            plugins = (xPlugins)xml.Deserialize(fs);        }        catch (Exception ex)        {            throw;        }    }}public abstract class Calculator{    [XmlElement("Multiple",typeof(Subtract))]    [XmlElement("divIDe",typeof(Operand))]    public List<Calculator> calculators{ get; set; }    public virtual int Calculate()    {        return 0;    }}public class Operator : Calculator{    public int value { get; set; }    public Operator() { }    public overrIDe int Calculate()    {        return value;    }}public class Add : Calculator{    public Add() { }    public overrIDe int Calculate()    {                 List<int> value = new List<int>();        foreach (Calculator calculator in calculators)        {            value.Add(calculator.Calculate());        }        return value.Sum();    }}public class Minus : Calculator{    public Minus() { }    public overrIDe int Calculate()    {        int value = calculators[0].Calculate();        for (int i = 1; i < calculators.Count; i++)        {            value -= calculators[i].Calculate();        }        return value;    }}public class divIDe: Calculator{     public divIDe() { }    public overrIDe int Calculate()    {        int value = calculators[0].Calculate();        for (int i = 1; i < calculators.Count; i++)        {            value /= calculators[i].Calculate();        }        return value;    }}public class Multiple : Calculator{    public Multiple() { }    public overrIDe int Calculate()    {        int value = calculators[0].Calculate();        for (int i = 1; i < calculators.Count; i++)        {            value *= calculators[i].Calculate();        }        return value;    }}//running testprivate voID button1_Click(object sender,EventArgs e)    {        readxml.getobject(ref this.plugins);        foreach (Calculator plugin in plugins.calculators)        {            plugin.Calculate();        }    }

我只需要用以下内容装饰Calculator属性:

[XmlElement("Multiple",typeof(Multiple))][XmlElement("Add",typeof(Add))][XmlElement("Subtract",typeof(divIDe))][XmlElement("divIDe",typeof(divIDe))][XmlElement("Operator",typeof(Operand))]
解决方法 我猜你想要使用XmlSerializer.
如果需要“多态”反序列化,则可以传递序列化程序应该知道的类型列表(如果它们都从相同的基类继承而不是从接口继承,则可以使用).

例:

List<Type> extraTypes = new List<Type>();extraTypes.Add(typeof(multiple));extraTypes.Add(typeof(add));extraTypes.Add(typeof(substract));extraTypes.Add(typeof(divIDe));var ser = new XmlSerializer(typeof(Foo),extraTypes.ToArray());

它在这里解释:
Serializing and restoring an unknown class

但是还有一个问题,在你的XML中,你的 *** 作数可以包含两种不同的类型: *** 作或参数(a,b,c,d),你不能在你的类中表示它.

我通常看到的是这个(我只实现了添加 *** 作,我假设表达式是数字):

public class Expression{  public virtual int Evaluate()  {  }}public class Add : Expression{  Expression _left;  Expression _right;  public Add(Expression left,Expression right)  {    _left = left;    _right = right;  }  overrIDe int Evalute()  {    return _left.Evalute() + _right.Evalute();  }}public class Parameter : Expression{  public int Value{get;set;}  public Parameter(string name)  {    // Use the name however you need.  }  overrIDe int Evalute()  {    return Value;  }}

这样你只有一个基类,所以一切都更简单.如果这有意义,我想将其反序列化并不困难.

编辑:
如果基类是Calculator(而不是Expression),则XML将如下所示:

<Calculator xsi:type="Multiple">  <calculators>    <Calculator xsi:type="Add">      <calculators>        <Calculator xsi:type="Operator">          <value>12</value>        </Calculator>      </calculators>    </Calculator>  </calculators></Calculator>

我创建了一个简单的计算器对象并将其序列化,这就是我所得到的.如果您将反序列化它,您将获得一个将返回12的计算器.

也许您可以使用XmlAttributes来更改XML中元素的名称,或者在最坏的情况下编写自己的反序列化器.

总结

以上是内存溢出为你收集整理的使用C#将xml反序列化为超类对象全部内容,希望文章能够帮你解决使用C#将xml反序列化为超类对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1251593.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存