Aen*_*dhe 11 c# xml arrays serialization nullable
这是我的班级:
public class Command
{
[XmlArray(IsNullable = true)]
public List<Parameter> To { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我序列化这个类的对象时:
var s = new XmlSerializer(typeof(Command));
s.Serialize(Console.Out, new Command());
Run Code Online (Sandbox Code Playgroud)
它按预期打印(省略xml标头和默认MS名称空间):
<Command><To xsi:nil="true" /></Command>
Run Code Online (Sandbox Code Playgroud)
当我拿这个xml并试图反序列化它时我被卡住了,因为它总是打印"Not null":
var t = s.Deserialize(...);
if (t.To == null)
Console.WriteLine("Null");
else
Console.WriteLine("Not null");
Run Code Online (Sandbox Code Playgroud)
如果强制反序列化器使我的列表为null,如果它在xml中为null?
如果您使用数组而不是列表,它会按预期工作
public class Command
{
[XmlArray(IsNullable = true)]
public Parameter[] To { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
呃,烦人不是吗。您可以通过使用 /keep 和 /debug 选项在程序集上运行 sgen.exe 来查看它的执行情况,以便您可以调试反序列化代码。它看起来大致是这样的:
\n\nglobal::Command o;\no = new global::Command();\nif ((object)(o.@To) == null) o.@To = new global::System.Collections.Generic.List<global::Parameter>();\nglobal::System.Collections.Generic.List<global::Parameter> a_0 = (global::System.Collections.Generic.List<global::Parameter>)o.@To;\n// code elided\n//...\nwhile (Reader.NodeType != System.Xml.XmlNodeType.EndElement && Reader.NodeType != System.Xml.XmlNodeType.None) {\n if (Reader.NodeType == System.Xml.XmlNodeType.Element) {\n if (((object)Reader.LocalName == (object)id4_To && (object)Reader.NamespaceURI == (object)id2_Item)) {\n if (!ReadNull()) {\n if ((object)(o.@To) == null) o.@To = new global::System.Collections.Generic.List<global::Parameter>();\n global::System.Collections.Generic.List<global::Parameter> a_0_0 = (global::System.Collections.Generic.List<global::Parameter>)o.@To;\n // code elided\n //...\n }\n else {\n // Problem here:\n if ((object)(o.@To) == null) o.@To = new global::System.Collections.Generic.List<global::Parameter>();\n global::System.Collections.Generic.List<global::Parameter> a_0_0 = (global::System.Collections.Generic.List<global::Parameter>)o.@To;\n }\n }\n }\n Reader.MoveToContent();\n CheckReaderCount(ref whileIterations1, ref readerCount1);\n}\nReadEndElement();\nreturn o;\nRun Code Online (Sandbox Code Playgroud)\n\n不少于 3 个地方确保 @To 属性不为 null。第一个是有一定道理的,当结构不存在时很难反序列化数据。第二个再次进行空测试,这是唯一真正好的测试。第三个问题是,ReadNull() 返回 true 但它仍然创建一个非 null 属性值。
\n\n如果您想区分空和空,那么您没有好的解决方案,只能手动编辑此代码。只有当你真的绝望并且班级 100% 稳定时才这样做。好吧,别这样做。Jo\xc3\xa3o 的解决方案是唯一好的解决方案。
\n