用属性覆盖属性 [英] Overriding a property with an attribute

查看:20
本文介绍了用属性覆盖属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to find a way to change the serialization behavior of a property.

假设我有这样的情况:

[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 进行序列化).

Now I want to serialize EmployeeRecord. I don't want the LastUpdated property from the Record class to be serialized. (I do want LastUpdated to be serialized when I serialize Record, though).

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

First I tried hiding the LastUpdated property by using the new keyword and then adding the XmlIgnore attribute:

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

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

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

But that didn't work. Then I tried making the base LastUpdated virtual and overriding it, keeping the attribute:

[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 属性,并愉快地进行了序列化业务.

This didn't work either. In both attempts the LastUpdated ignored the XmlIgnore attribute and happily went about its business of serializing.

有没有办法让我想做的事情发生?

Is there a way to make what I'm trying to do happen?

推荐答案

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

First, the [Serializable] attr has nothing to do with the XmlSerializer. That is a red herring. [Serializable] is meaningful to System.Runtime.Serialization, while the XmlSerializer lives in System.Xml.Serialization. If you are decorating your class with [Serializable] and your members with [XmlIgnore] then you are probably confusing yourself or other readers of your code.

.NET 中的 XmlSerialization 非常灵活.根据序列化的完成方式,直接由您或间接由 Web 服务运行时完成 - 您有不同的方式来控制事物.

XmlSerialization in .NET is very flexible. Depending on how the serialization is being done, directly by you or indirectly, let's say by the web services runtime - you have different ways to control things.

一种选择是使用 propertyNameSpecified 模式来打开或关闭 XML 序列化中的属性.假设您有以下代码:

One option is to use the propertyNameSpecified pattern to turn ON or OFF the property in XML Serialization. Suppose you have this code:

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

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

Then, if LastModifiedSpecified is false in an instance, the LastModified field will not be serialized for that instance. In the constructor for your type, you can set LastModifiedSpecified to always be true in the base type, and always false in the derived type. The actual boolean - LastModifiedSpecified - never gets serialized because it is marked XmlIgnore.

这个小技巧被记录在这里.

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

Your other option is to use XmlAttributeOverrides, which is a way of dynamically providing the set of XML serialization attributes (like XmlElementAttribute, XmlIgnoreAttribute, XmlRootAttribute, and so on...) - dynamically providing those attributes to the serializer at runtime. The XmlSerializer, instead of inspecting the type itself for those attributes, will just walk through the list of override attributes provided to its constructor.

    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 服务一样.

In your case, you would provide an XmlIgnoreAttribute as an override, but only when serializing the derived type. (or whatever) This works only when you directly instantiate the XmlSerializer - it won't work when serialization is done implicitly by the runtime, as with web services.

干杯!

这篇关于用属性覆盖属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆