XmlSerializer为x86和x64生成不同的输出

时间:2017-04-18 07:47:20

标签: c# .net xml serialization namespaces

我有以下示例代码,它为x86和x64生成不同的输出。

class SampleSerializer
{
   public static string Serialize(string[] samples)
   {
      var xmlDocument = string.Empty;

      var xmlSerializer = new XmlSerializer(typeof(string[]));
      using (var ms = new MemoryStream())
      {
         xmlSerializer.Serialize(
            ms,
            samples);

         xmlDocument = Encoding.UTF8.GetString(ms.ToArray());
      }

      return xmlDocument;
   }
}

class Program
{
   static void Main(string[] args)
   {
      var samples = new string[] { };

      var doc = SampleSerializer.Serialize(samples);

      Console.WriteLine(doc);
   }
}

当平台目标是x86时,输出为:

<?xml version="1.0"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

当平台目标是x64时,输出为:

<?xml version="1.0"?>
<ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />

您可以使用任何CPU和首选32位设置或取消设置来实现相同的功能。

如果仔细查看,名称空间xsixsd的顺序是不同的。为什么会这样?我希望命名空间的顺序与平台无关。

1 个答案:

答案 0 :(得分:4)

XmlSerializer在内部使用Hashtable来保留名称空间(this one,然后是this one),因此您可以将示例简化为以下内容:

var hash = new Hashtable();
hash.Add("xsi", null);
hash.Add("xsd", null);

foreach (var name in hash.Keys)
{
    Console.WriteLine(name);
}

x86:

xsi
xsd

64:

xsd
xsi

转载!从技术上讲,这是预期的,按照MSDN

  

ICollection中键的顺序未指定

如果这还不够,我们可以在这里开始行走,并猜测为何如此。我最好的猜测是,Keys的顺序取决于Keys的哈希码。

好的,我们试试吧:

Console.WriteLine("xsi: {0:x8}", "xsi".GetHashCode());
Console.WriteLine("xsd: {0:x8}", "xsd".GetHashCode());

86:

xsi: c5864a25
xsd: c2b84cce

64:

xsi: b9b66082
xsd: b9b66087

相同的字符串,不同平台的不同哈希码!

但是,根据MSDN

的预期
  

哈希码本身并不保证稳定。对于单个版本的.NET Framework,不同版本的.NET Framework和跨平台(例如32位和64位)的相同字符串的哈希代码可能不同。在某些情况下,它们甚至可能因应用领域而异。

何浩,“他们甚至可以因应用领域而异”!

现在我不会依赖XmlSerializer总能产生稳定的结果..