Skip to content
Next Next commit
Bugfix: System.Xml.Serialization: Compiler.GetTempAssemblyName is not…
… persistent under .NET Core

The implementation of String.GetHashCode() was persistent by default in .NET Framework. allowing to predictably name an XmlSerializers.{HashCode}.dll containing the pre-generated serializers.
In .NET Core / .NET 5, String.GetHashCode() is no longer persistent, so the value of ns.GetHashCode() will change during each run, preventing it from picking up the XmlSerializers dll correctly.
  • Loading branch information
TalAloni authored Jan 1, 2021
commit c8d9b20fd20caa826ba8ba139d51dd472d227e22
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,25 @@ internal TextWriter Source

internal static string GetTempAssemblyName(AssemblyName parent, string? ns)
{
return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + ns.GetHashCode());
return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + GetPersistentHashCode(ns));
}

/// <remarks>
/// Returns the same value returned by .NET Framework 64-bit String.GetHashCode()
/// </remarks>
private static int GetPersistentHashCode(string value)
{
int hash1 = 5381;
int hash2 = hash1;

for (int i = 0; i < value.Length && value[i] != '\0'; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ value[i];
if (i == value.Length - 1 || value[i + 1] == '\0')
break;
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
}
return hash1 + (hash2 * 1566083941);
}
}
}