连载bool?错误反映类型

时间:2012-03-30 12:00:55

标签: c# xml xml-serialization

我有一个像

这样的课程
   [Serializable]
    public class MyClass
    {
        [XmlAttribute]
        public bool myBool { get; set; }
    }

但是当xml中不存在该属性时,这会将bool的值序列化为false。 当属性不在xml中时,我希望该属性为null。

所以我试过这个

[Serializable]
public class MyClass
{
    [XmlAttribute]
    public bool? myBool { get; set; }
}

然后是序列化器错误

Type t = Type.GetType("Assembly.NameSpace.MyClass");
                XmlSerializer mySerializer = new XmlSerializer(t); //error "There was an error reflecting type"

请举个例子说明我能做到这一点。我知道在SO上有一些相关的问题,但没有任何东西能说明如何用可空的bool来克服反射误差。感谢。

4 个答案:

答案 0 :(得分:10)

您需要使用“* Specified”字段模式来控制它(请参阅MSDN上的“控制生成的XML”):

[Serializable]
public class MyClass
{
    [XmlAttribute]
    public bool myBool { get; set; }

    [XmlIgnore]
    public bool myBoolSpecified;
}

逻辑现在变为:

  • 如果!myBoolSpecified,则myBool逻辑null
  • 否则,请使用true
  • falsemyBool

答案 1 :(得分:3)

有关处理可空字段和XML属性的信息,请查看this。这里也有类似的question。基本上,序列化程序无法处理定义为可为空的XML属性字段,但有一种解决方法。

即2个属性,一个包含可空(不是XML存储),另一个用于读/写(XML属性存储为字符串)。也许这可能就是你所需要的?

private bool? _myBool;
[XmlIgnore]
public bool? MyBool
{
    get
    {
        return _myBool;
    }
    set
    {
        _myBool = value;
    }
}

[XmlAttribute("MyBool")]
public string MyBoolstring
{
    get
    {
        return MyBool.HasValue
        ? XmlConvert.ToString(MyBool.Value)
        : string.Empty;
    }
    set
    {
        MyBool =
        !string.IsNullOrEmpty(value)
        ? XmlConvert.ToBoolean(value)
        : (bool?)null;
    }
}

答案 2 :(得分:2)

您可以使用 XmlElementAttribute.IsNullable

[Serializable]
public class MyClass
{
    [XmlElement(IsNullable = true)]
    public bool? myBool { get; set; }
}

答案 3 :(得分:1)

问题是可空类型必须定义为元素(默认)而不是属性。

原因是当值为null时,它可以表示为<mybool xs:nil="true"/>,因为不能表示为属性

看一下这个片段:

[Serializable]
public class MyClass
{
    // removed the attribute!!!
    public bool? myBool { get; set; }
}

XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
var stream = new MemoryStream();
serializer.Serialize(stream, new MyClass(){myBool = null});
Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray()));

输出:

<?xml version="1.0"?>
<MyClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.o
rg/2001/XMLSchema-instance">
  <myBool xsi:nil="true" /> <!-- NOTE HERE !!! -->
</MyClass>