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

Mar*_*ila 3 .net c# 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);
   }
}
Run Code Online (Sandbox Code Playgroud)

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

<?xml version="1.0"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
Run Code Online (Sandbox Code Playgroud)

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

<?xml version="1.0"?>
<ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
Run Code Online (Sandbox Code Playgroud)

您可以通过设置或取消设置“任何CPU和首选32位”来实现相同的效果。

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

Lan*_*kin 5

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

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

foreach (var name in hash.Keys)
{
    Console.WriteLine(name);
}
Run Code Online (Sandbox Code Playgroud)

x86:

xsi
xsd
Run Code Online (Sandbox Code Playgroud)

x64:

xsd
xsi
Run Code Online (Sandbox Code Playgroud)

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

ICollection中的键顺序未指定

如果那还不够,我们可以在这里开始如履薄冰,猜想为什么会这样。我最好的猜测是,键的顺序取决于键的哈希码。

好吧,让我们尝试:

Console.WriteLine("xsi: {0:x8}", "xsi".GetHashCode());
Console.WriteLine("xsd: {0:x8}", "xsd".GetHashCode());
Run Code Online (Sandbox Code Playgroud)

x86:

xsi: c5864a25
xsd: c2b84cce
Run Code Online (Sandbox Code Playgroud)

x64:

xsi: b9b66082
xsd: b9b66087
Run Code Online (Sandbox Code Playgroud)

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

但是,这也是每个MSDN所期望的:

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

呵呵呵,“它们甚至可以因应用程序域而异”!

现在我不再依赖XmlSerializer总是产生稳定的结果。