C# 有条件地序列化/反序列化属性

C# 有条件地序列化/反序列化属性,c#,xml,serialization,C#,Xml,Serialization,我有一个类,其对象必须根据bool值序列化/反序列化属性 [System.SerializableAttribute()] public class Foo { private string myField; private bool myFieldSerializes; //Parameterless construction for serializing purposes public Foo() { } public Foo(string my

我有一个类,其对象必须根据bool值序列化/反序列化属性

[System.SerializableAttribute()]
public class Foo
{
    private string myField;
    private bool myFieldSerializes;

    //Parameterless construction for serializing purposes
    public Foo() { }

    public Foo(string myField, bool myFieldSerializes)
    {
        this.myField = myField;
        this.myFieldSerializes = myFieldSerializes;
    }

    public string MyField
    {
        get {return this.myField;}
        set {this.myField = value;}
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool MyFieldSerializes
    {
        get {return this.myFieldSerialzes;}
        set {this.myFieldSerialzes = value;}
    }
}
这就是它的工作原理:

  • 如果我创建一个实例并将myFieldSerializes设置为“true”,则在序列化对象(使用XMLSerialize)时,myField必须序列化(包含在XML消息中)。如果设置为“false”,则应忽略它

  • 反序列化(使用XMLDeserialize)时,布尔myFieldSerializes应该告诉我myField是否已反序列化(换句话说,它存在于XML文件中)

实现这种行为的方法是什么


谢谢!:)

似乎您可以使用ShouldSerialize方法:

您可以实现接口,该接口允许您指定要序列化和反序列化的内容

因此,您需要实现一个
GetObjectData
方法,如:

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    // Use the AddValue method to specify serialized values.
    info.AddValue("props", myProperty_value, typeof(string));

}
以及一个构造函数,它将
SerializationInfo
StreamingContext
作为如下参数

// The special constructor is used to deserialize values.
public Foo(SerializationInfo info, StreamingContext context)
{
    // Reset the property value using the GetValue method.
    myProperty_value = (string) info.GetValue("props", typeof(string));
}

通过这种方式,您可以在序列化和反序列化过程中决定要做什么(例如设置属性值或不设置属性值)

您的要求与
XmlSerializer
的属性名称指定模式相匹配。从:

如果架构包含可选的元素。。。[1]选项是使用特殊模式创建XmlSerializer识别的布尔字段,并将XmlIgnoreAttribute应用于该字段。模式以propertyNameSpecified的形式创建。例如,如果有一个名为“MyFirstName”的字段,您还将创建一个名为“MyFirstNameSpecified”的字段,该字段指示XmlSerializer是否生成名为“MyFirstName”的XML元素

此模式的便利之处在于,除了文档中的行为之外,在反序列化过程中,
XmlSerializer
将在遇到属性时将propertyNameSpecified设置为true,这正是您所需要的。因此,您的类应该如下所示:

public class Foo
{
    private string myField;
    private bool myFieldSerializes;

    //Parameterless construction for serializing purposes
    public Foo() { }

    public Foo(string myField, bool myFieldSerializes)
    {
        this.myField = myField;
        this.myFieldSerializes = myFieldSerializes;
    }

    [XmlElement(IsNullable = true)] // Emit a value even when null as long as MyFieldSpecified == true
    public string MyField
    {
        get { return this.myField; }
        set { this.myField = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool MyFieldSpecified { get { return myFieldSerializes; } set { myFieldSerializes = value; } }
}
(将
[XmlElement(IsNullable=true)]
添加到
MyField
属性可确保在
MyFieldSpecified==true
时始终发出元素,即使字段本身为
null


原型。

我不完全清楚您希望它如何工作,但示例代码可能是您想要的。请参阅类似的答案,这是一种方法!!我也有同样的想法要建议。这里是我的类似答案的详细帖子,供进一步参考,谢谢!事实上,我所处的情况就是这样:XSD.exe工具转换为“propertyName”和布尔“propertynamemspecified”的XSD文件中的可选属性。我认为我必须手动控制序列化,但我看到序列化程序可以完成所有工作:)这也可以用于反序列化吗?当我需要有选择地从XML反序列化属性值时?
public class Foo
{
    private string myField;
    private bool myFieldSerializes;

    //Parameterless construction for serializing purposes
    public Foo() { }

    public Foo(string myField, bool myFieldSerializes)
    {
        this.myField = myField;
        this.myFieldSerializes = myFieldSerializes;
    }

    [XmlElement(IsNullable = true)] // Emit a value even when null as long as MyFieldSpecified == true
    public string MyField
    {
        get { return this.myField; }
        set { this.myField = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool MyFieldSpecified { get { return myFieldSerializes; } set { myFieldSerializes = value; } }
}