XmlSerializer的在空引用异常的依赖性结果(XmlSerializer with depe

2019-11-02 07:22发布

我正在与我自己的类的Xml序列化的问题。 这是一个派生类,不自然有一个参数的构造函数 - 我不得不添加一个只为序列化的缘故。 当然,因为我快成一种依赖/顺序问题。

下面是一个简化的,我希望还是能说明问题(我保留,以增加说明如果事实证明我并没有抓住问题的权利 - 我只是不想转储一个复杂的对象模型对你:))

public class Base{
  public virtual Vector Value{ get; set;}
}

public class Derived : Base{

  public Vector Coefficient { get; set; }
  public override Vector Value{
     get { return base.Value * Coefficient; }
     set { base.Value = value / Coefficient; }
  }
}

编辑 :为了避免混淆,我取代的值类型double原始柱与未示出的,这里Vector类型

当XmlSerializer的反序列化Derived ,我碰上空值例外-无论base.Valuethis.Coefficientnull

有没有什么办法解决这一问题?

Answer 1:

看来,这里的许多问题,从使用您的域模型系列化干。 现在,这可以工作,但它也可以是巨大的问题,如果您的域模型从串行想要做什么甚至略有偏差。

我强烈建议尝试添加该数据的第二平行表示,作为“DTO模式” - 意思是:一组对象,他们的工作就是代表了序列化的数据。 s,而不是使用计算和依赖复杂的属性,你只需要:

public double SomeValue { get; set; }

等关键的一点是这是很简单,代表了数据 ,而不是系统的规则。 您序列化到/从这个模型 - 这不应该是简单的 - 你从你的域模型映射这/。 转换运算符是有用的,但一个简单的“ToDomainModel” /“FromDomainModel”法正常工作了。 同样,像AutoMapper工具可以帮助,但DTO到/从域代码15行是不会伤害任何。

这避免了与问题:

  • 建设者
  • 非公共成员
  • 分配顺序
  • 只读成员
  • 版本

和一系列的系列化等常见的痛点。



Answer 2:

与你的价值getter和setter的一个问题是,如果系数不以反序列化的值时,时加载,那么它将被零次失误造成的鸿沟。 更糟的是,它可能不破,而是真正做到了对计算不正确的值,因为系数可能有存储在它的反序列化预值。 下面将通过零状况解决鸿沟,希望第二正确更新值,如果系数载荷。 事实上,这些情况下通常处理由串行化非计算的值,然后所导出的属性使用[XmlIgnoreAttribute]更好。

public class Derived : Base{


    public override double Value{
       get { return _coefficient; }
       set { 
          if(Coefficient == 0){
          base.Value = value;
       }else{
           base.Value = value / Coefficient; 
       }
    }

   private double _coefficient;
   public double Coefficient{
       get { return _coefficient; }
       set { 
           if(Coefficient == 0)
           {
               temp = base.Value;
               _coefficient = value;
               Value = temp; 
           }
           else{
                _coefficient = value;
           }
    }

}


// Example by serializing unmodified value
public double Coefficient { get; set; }
public double BaseValue { get; set; }

[XmlIgnoreAttribute]
public double Value
{
   get { return BaseValue * Coefficient; }
   set 
   { 
         if(Coefficient != 0){
            BaseValue = value / Coefficient;
         }else{
            BaseValue = value;
         }
    }


Answer 3:

你需要告诉你的基础对象导出项目序列化。 尝试:

[XmlInclude(typeof(Derived))]
public class Base {

另外,您也可以在运行时解释:

public XmlSerializer(Type type, Type[] extraTypes){..}

在你的情况: new XmlSerializer(typeof(Base), new Type[] { typeof(Derived), ..});

而为了让事情变得更加通用的,如果有一个巨大的层次结构,你可以使用反射来获取的派生类型的列表:

// You'll want to cache this result, and it could be a lot of work to run this
// multiple times if you have lots of classes
var knownTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
t => typeof(Base).IsAssignableFrom(t)).ToArray();
var serializer = new XmlSerializer(typeof(Base), knownTypes);


文章来源: XmlSerializer with dependencies results in Null reference exception