当前位置:  开发笔记 > 编程语言 > 正文

使用属性覆盖属性

如何解决《使用属性覆盖属性》经验,为你挑选了2个好方法。

我正试图找到一种方法来改变属性的序列化行为.

可以说我有这样的情况:

[Serializable]
public class Record
{
   public DateTime LastUpdated {get; set; }

   // other useful properties ...
}

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }

   // other useful properties ...
}

现在我想序列化EmployeeRecord.我不希望序列化Record类中的LastUpdated属性.(我确实希望在序列化Record时序列化LastUpdated).

首先,我尝试使用new关键字隐藏LastUpdated属性,然后添加XmlIgnore属性:

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }

   [XmlIgnore]
   public new DateTime LastUpdated {get; set; }
   // other useful properties ...
}

但那没用.然后我尝试将基础LastUpdated虚拟化并覆盖它,保留属性:

[Serializable]
public class Record
{
   public virtual DateTime LastUpdated {get; set; }

   // other useful properties ...
}

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }

   [XmlIgnore]
   public override DateTime LastUpdated {get; set; }
   // other useful properties ...
}

这也不起作用.在这两次尝试中,LastUpdated都忽略了XmlIgnore属性,并愉快地开展了序列化业务.

有没有办法让我正在尝试做的事情发生?



1> Cheeso..:

首先,[Serializable] attr与XmlSerializer无关.那是一只红鲱鱼.[Serializable]对System.Runtime.Serialization有意义,而XmlSerializer则存在于System.Xml.Serialization中.如果您使用[Serializable]和您的成员使用[XmlIgnore]装饰您的课程,那么您可能会困惑自己或您的代码的其他读者.

.NET中的XmlSerialization非常灵活.取决于序列化的完成方式,直接由您或间接完成,比如说Web服务运行时 - 您可以通过不同的方式来控制事物.

一种选择是使用propertyName Specified模式在XML Serialization中打开或关闭属性.假设你有这个代码:

public class TypeA
{ 
  public DateTime LastModified;
  [XmlIgnore]
  public bool LastModifiedSpecified;
}

然后,如果实例中的LastModifiedSpecified为false,则不会为该实例序列化LastModified字段.在类型的构造函数中,可以将LastModifiedSpecified设置为在基类型中始终为true,并在派生类型中始终为false.实际的布尔值 - LastModifiedSpecified - 永远不会被序列化,因为它被标记为XmlIgnore.

这里记录了这个小技巧.

您的另一个选择是使用XmlAttributeOverrides,这是一种动态提供XML序列化属性集的方法(如XmlElementAttribute,XmlIgnoreAttribute,XmlRootAttribute等等) - 在运行时动态地将这些属性提供给序列化程序.XmlSerializer不是为这些属性检查类型本身,而是遍历提供给其构造函数的覆盖属性列表.

    var overrides = new XmlAttributeOverrides();
    // ....fill the overrides here....
    // create a new instance of the serializer specifying overrides
    var s1 = new XmlSerializer(typeof(Foo), overrides);
    // serialize as normal, here.

这在此处更详细地说明.

在您的情况下,您将提供XmlIgnoreAttribute作为覆盖,但仅在序列化派生类型时.(或其他)只有在直接实例化XmlSerializer时才有效 - 当运行时隐式执行序列化时,它不起作用,就像Web服务一样.

干杯!



2> Marc Gravell..:

我能想到的最好的......

[Serializable]
public class Record
{
   public DateTime LastUpdated {get; set; }
   public virtual bool ShouldSerializeLastUpdated() {return true;}
   // other useful properties ...
}

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }
   public override bool ShouldSerializeLastUpdated() {return false;}
   // other useful properties ...
}

基本上,有一些模式XmlSerializer值得尊重; public bool ShouldSerialize*()public bool *Specified {get;set;}(请注意,你应该标记*Specified[XmlIgnore]太...).

不太优雅,我会授予; 但XmlSerializer只关注公众成员,所以你甚至无法隐藏它们(缺少[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]).

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有