I have two clients that create IPAddress
instances from the same byte[]
and send it to the server over WCF (using DataContractSerializer
).
On the server, these IPAddress
instances are inserted as keys in a dictionary but for some reason they're added as different keys.
When logging I see that they're equal but GetHashCode
returns different results.
var client1Address = // sent from client1
var client2Address = // sent from client2
Console.WriteLine(client1Address.Equals(client2Address));
Console.WriteLine(client1Address.GetHashCode().Equals(client2Address.GetHashCode()));
Output:
true
false
How can equal IPAddress
instances return different GetHashCode
results?
The GetHashCode
implementation of IPAddress
for IPv6 is:
if (m_HashCode == 0)
{
m_HashCode = StringComparer.InvariantCultureIgnoreCase.GetHashCode(ToString());
return m_HashCode;
}
To avoid recalculating the hash code again and again, they’re storing the result in a private member. This private member is then serialized to the remote server.
The thing is, that StringComparer.InvariantCultureIgnoreCase.GetHashCode(ToString())
returns different results on different OS versions, and since m_HashCode
is serialized as well, the server does not recalculate it.
This results in two identical IPAddress
instances with different GetHashCode
results.
I think that the private member m_HashCode
should be marked as [NonSerialized]
, that will cause GetHashCode
to re-generate the hash code locally and correctly.
As a workaround, I interfered in the serialization process and serialized as a byte[]
.
Here's the bug on VisualStudio connect. This link is dead as the bug was closed for these reasons:
"Thank you for reporting this issue. Unfortunately, our team is not able to address this issue due to other, higher priority items. Further, any changes to the serialized content of a type result in a risk of breaking apps that have taken a dependency on that behavior. "
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With