Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 何时使用ShouldSerializeXXX与XmlIgnoreAttribute进行XML序列化_C#_C# 4.0_Serialization_Xml Serialization_Xmlserializer - Fatal编程技术网

C# 何时使用ShouldSerializeXXX与XmlIgnoreAttribute进行XML序列化

C# 何时使用ShouldSerializeXXX与XmlIgnoreAttribute进行XML序列化,c#,c#-4.0,serialization,xml-serialization,xmlserializer,C#,C# 4.0,Serialization,Xml Serialization,Xmlserializer,我寻找了一些在xml序列化和反序列化期间忽略类属性的示例。我发现了三种不同的方法,但不知道应该在什么时候使用。我特别感兴趣的是,哪一个更好 属性 公共类项目 { [XmlIgnore] 公共字符串名称{get;set;} } 以开头的方法应序列化… 公共类项目 { 公共字符串名称{get;set;} 公共bool应序列化名称() { 返回false; } } 属性 公共类项目 { [非串行化] 公共字符串名称{get;set;} } 如果对和上的XmlIgnoreAttribtue和Non

我寻找了一些在xml序列化和反序列化期间忽略类属性的示例。我发现了三种不同的方法,但不知道应该在什么时候使用。我特别感兴趣的是,哪一个更好

  • 属性

    公共类项目
    {
    [XmlIgnore]
    公共字符串名称{get;set;}
    }
    
  • 开头的方法应序列化…

    公共类项目
    {
    公共字符串名称{get;set;}
    公共bool应序列化名称()
    {
    返回false;
    }
    }
    
  • 属性

    公共类项目
    {
    [非串行化]
    公共字符串名称{get;set;}
    }
    

  • 如果对和上的
    XmlIgnoreAttribtue
    NonSerializedAttribute
    之间的差异有一些解释,我无法找到有关何时使用
    XmlIgnoreAttribtue
    以及何时应序列化
    模式的信息。我用XmlSerializer尝试了这两种方法,两种方法都能如期工作。

    1和2之间的基本区别在于它们生成的结果不同。如果希望从类型的架构中排除成员,请使用。如果希望有条件地包括成员,请使用或。(最后,如中所述,
    XmlSerializer
    忽略了选项3中的内容)

    要查看#1和#2之间的差异,可以使用为类型生成模式。为版本#1生成以下架构,并完全省略
    名称
    成员:

    <xs:complexType name="Item" />
    
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
    </xs:sequence>
    
    出现这种差异是因为
    XmlSerializer
    xsd.exe
    都执行静态类型分析,而不是动态代码分析。这两个工具都无法确定案例2中的
    Name
    属性将始终被跳过,因为这两个工具都没有尝试对
    ShouldSerializeName()
    的源代码进行反编译,以证明它总是返回
    false
    。因此,
    Name
    将出现在版本2的模式中,尽管在实践中从未出现过。如果随后创建一个web服务并使用发布模式(或只是手动使其可用),将为这两种类型生成不同的客户机——一个没有
    名称
    成员,另一个有

    当所讨论的属性是不可为null的值类型时,可能会产生额外的复杂性。考虑以下三个版本的<代码>项目< /代码>。首先,具有无条件包含值属性的版本:

    public class Item
    {
        public int Id { get; set; }
    }
    
    public class Item
    {
        [XmlIgnore]
        public int Id { get; set; }
    }
    
      <xs:complexType name="Item" />
    
    public class Item
    {
        public int Id { get; set; }
    
        public bool ShouldSerializeId()
        {
            return false;
        }
    }
    
    生成始终存在
    Id
    的以下架构:

      <xs:complexType name="Item">
        <xs:sequence>
          <xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:int" />
        </xs:sequence>
      </xs:complexType>
    
    生成完全忽略
    Id
    属性的以下架构:

    public class Item
    {
        public int Id { get; set; }
    }
    
    public class Item
    {
        [XmlIgnore]
        public int Id { get; set; }
    }
    
      <xs:complexType name="Item" />
    
    public class Item
    {
        public int Id { get; set; }
    
        public bool ShouldSerializeId()
        {
            return false;
        }
    }
    
    生成以下架构,其中
    Id
    仅有条件地存在:

      <xs:complexType name="Item">
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="1" name="Id" type="xs:int" />
        </xs:sequence>
      </xs:complexType>
    
    有关绑定到条件序列化值成员的更多详细信息,请参阅和

    这是主要区别,但也有次要区别,可能会影响您的选择:

    • [XmlIgnore]
      不能在派生类中被重写,但是
      ShouldSerializeXXX()
      标记为虚拟时可以被重写;有关示例,请参见

    • 如果一个成员不能被
      XmlSerializer
      序列化,例如,因为它引用了一个类型,那么用
      [XmlIgnore]
      标记该成员将允许序列化包含的类型,而添加
      ShouldSerializeXXX(){return false;}
      将不允许序列化包含的类型,因为如前所述,XmlSerializer只执行静态类型分析。例如:

      public class RootObject
      {
          // This member will prevent RootObject from being serialized by XmlSerializer despite the fact that the ShouldSerialize method always returns false.
          // To make RootObject serialize successfully, [XmlIgnore] must be added.
          public NoDefaultConstructor NoDefaultConstructor { get; set; }
      
          public bool ShouldSerializeNoDefaultConstructor() { return false; }
      }
      
      public class NoDefaultConstructor
      {
          public string Name { get; set; }
          public NoDefaultConstructor(string name) { this.Name = name; }
      }
      
      无法由
      XmlSerializer
      序列化

    • [XmlIgnore]
      特定于
      XmlSerializer
      ,但
      ShouldSerializeXXX()
      被其他序列化程序使用,包括和

    • 如注释中所述,在Visual Studio中重命名有条件序列化的属性不会自动重命名相应的
      ShouldSerializeXXX()
      方法名,从而导致潜在的维护问题


    如果它们都符合您的标准,请选择您喜欢的。PS
    ShouldSerializeXXX
    版本是个糟糕的主意,不要用那个@DavidG:Con你可以争论为什么使用
    ShouldSerializeXXX
    是个糟糕的主意。你会用所有这些额外的方法污染你的模型,而属性不会。不使用ShouldSerializeXXX的另一个原因是在实现了所有这些之后,当后来有人进来需要更改字段名称时会发生什么情况。该任务现在在开发人员不知道的情况下中断了序列化。XmlSerializer似乎没有像JSON.net那样的ContractResolver,这使得ShouldSerialize成为动态包含/排除成员的唯一方法。我们使用T4模板生成ShouldSerializeXxxx函数。我们有这么多属性,生成的文件有10000行代码。非常感谢您的详细解释。这给了我一个完美的决策指导。伟大的