我有一个带有虚拟属性的基类,并且派生类型覆盖了该虚拟属性。该类型可以序列化为XML。我试图做的是当对象属于派生类型时,不保留项目列表属性。为此,派生类使用[XmlIgnore]属性装饰了重写的属性。基类中的虚拟属性不适用于XmlIgnore属性。由于某种原因,即使对象是派生类型(DynamicCart),项目列表也会被序列化。

当我将XmlIgnore属性应用于基类中的虚拟属性时,列表不会序列化到文件。

public class ShoppingCart
{
   public virtual List<items> Items{get; set;}

   //and other properties

   public void SerializeToXML (string filePath)
   {
     var xmlSerializer = new XmlSerializer(this.GetType());
     textWriter = new System.IO.StreamWriter(filePath);
     xmlSerializer.Serialize(textWriter, this);
     textWriter.Flush();
     textWriter.Close();
   }
}

//A cart that is populated by algo based on parameters supplied by user. I have no need to
//persist the actual items across sessions.
class DynamicCart: ShoppingCart
{
   [XmlIgnore]
   public override List<items>{get;set;}
   //and other properties
}

class Shop
{
   ShoppingCart cart = new DynamicCart();
   PopulateCart(cart);
   cart.serializeToXML(<PATH TO FILE>);
}

最佳答案

您可以通过在基类中添加虚拟ShouldSerialize***方法来实现。例如:

[XmlInclude(typeof(Sub))]
public class Base
{
    public virtual string Prop { get; set; }

    public virtual bool ShouldSerializeProp() { return true; }
}

public class Sub : Base
{
    public override string Prop { get; set; }

    public override bool ShouldSerializeProp() { return false; }
}

internal class Program
{
    private static void Main()
    {
        var o = new Sub { Prop = "Value" };

        var baseSer = new XmlSerializer(typeof (Base));
        var subSer = new XmlSerializer(typeof (Sub));

        Console.Out.WriteLine("BASE:");
        baseSer.Serialize(Console.Out, o);
        Console.Out.WriteLine();

        Console.Out.WriteLine("SUB:");
        subSer.Serialize(Console.Out, o);
        Console.Out.WriteLine();

        Console.ReadLine();
    }
}

这产生(稍微整理):
BASE:
<Base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Sub">
  <Prop>Value</Prop>
</Base>

SUB:
<Sub />

该方法必须在ShouldInclude...之后包含要考虑的属性的确切名称。

10-07 19:34
查看更多