我有两个客户端从相同 IPAddress
创建byte[]
个实例,并通过WCF将其发送到服务器(使用DataContractSerializer
)。
在服务器上,这些IPAddress
实例作为键插入字典中,但出于某种原因,它们被添加为不同的键。
登录时,我发现它们相同,但GetHashCode
会返回不同的结果。
var client1Address = // sent from client1
var client2Address = // sent from client2
Console.WriteLine(client1Address.Equals(client2Address));
Console.WriteLine(client1Address.GetHashCode().Equals(client2Address.GetHashCode()));
输出:
true
false
等同IPAddress
个实例如何返回不同的GetHashCode
结果?
答案 0 :(得分:16)
IPv6的IPAddress
GetHashCode
implementation为:
if (m_HashCode == 0)
{
m_HashCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode(ToString());
return m_HashCode;
}
为避免反复重新计算哈希码,他们将结果存储在私有成员中。然后将此私有成员序列化到远程服务器。
问题是,StringComparer.InvariantCultureIgnoreCase.GetHashCode(ToString())
在不同的OS版本上返回不同的结果,并且由于m_HashCode
也被序列化,因此服务器不会重新计算它。
这导致两个相同的IPAddress
个实例,结果不同GetHashCode
。
我认为私有成员m_HashCode
应标记为[NonSerialized]
,这将导致GetHashCode
在本地正确地重新生成哈希码。
作为一种解决方法,我干扰了序列化过程并序列化为byte[]
。
Here's the bug on VisualStudio connect。由于这些原因导致错误被关闭,此链接已经死亡:
"感谢您报告此问题。很遗憾,由于其他优先级较高的项目,我们的团队无法解决此问题。此外,对类型的序列化内容的任何更改都会导致破坏已依赖该行为的应用程序的风险。 "