Simon Lindgren
Simon Lindgren

Reputation: 510

.NET Hashtable - "Same" key, different hashes

Is it possible for two .net strings to have different hashes? I have a Hashtable with amongst others the key "path". When I loop through the elements in the table to print it, i can see that the key exists.

When trying to looking it up however, there is no matching element. Debugging suggests that the string I'm looking for has a different hash than the one I'm supplying as the key.

This code is in a Castle Monorail project, using brail as a view engine. The key I'm looking for is inserted by a brail line like this:

UrlHelper.Link(node.CurrentPage.LinkText, {@params: {@path: "/Page1"}})

Then, in this method (in a custom IRoutingRule):

public string CreateUrl(System.Collections.IDictionary parameters)
{
    PrintDictionaryToLog(parameters);
    string url;
    if (parameters.Contains("path")) {
        url = (string)parameters["path"];
    }
    else {
        return null;
    }
}

The key is printed to the log, but the function returns null. I didn't know this could even be a problem with .net strings, but I guess this is some kind of encoding issue?

Oh, and this is running mono.

As per request, here is the relevant line from the log:

2010-03-08 22:58:00,504 [7] DEBUG Knickle.Framework.Routing.PageRoute (null) - Parameters: {System.String controller=null, System.String path=Page1, System.String path=/Page1, System.String action=null, System.String area=null}

Also, here I have added a line of code above the log printing call:

parameters.Add("path", "Page1");

Take a look in the log, and you'll notice that there are two "path" keys. The debugger shows both keys in different places in the table.

Upvotes: 3

Views: 1251

Answers (5)

Patrick McEvoy
Patrick McEvoy

Reputation: 682

It's this line that does it [Castle.MonoRail.Framework.Services.DefaultUrlBuilder:397]...

// Forces copying entries to a non readonly dictionary, preserving the original one
parameters = new Hashtable(parameters, StringComparer.InvariantCultureIgnoreCase);

If the IEqualityComparer is removed the issue disappears.

If this is a mono bug (which I think it must be), it's still an issue with mono 2.10.8.1 (Debian 2.10.8.1-5ubuntu1).

A test case needs writing and filing.

Upvotes: 1

Monoman
Monoman

Reputation: 731

Which version of Mono, you were using? It could be a bug in Mono, if so a bug report would be welcome.

But yeah I agree with Seva that probably the cause is some trailing spaces or separators or some other encoding problem that made the strings differ in some subtle way and result in different hashes.

Upvotes: 0

kemiller2002
kemiller2002

Reputation: 115488

Here is the link to MSDN on GetHashCode for Strings. If they are equal, the hashcodes should match, however if they are not equal, they could still have the same hash (however small that possibility might be).

http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx

From the article:

If two string objects are equal, the GetHashCode method returns identical values. However, there is not a unique hash code value for each unique string value. Different strings can return the same hash code.

Upvotes: 2

JaredPar
JaredPar

Reputation: 754745

Strings which are equal as according to StringComparison.Ordinal, or more simply String.Equals, will have the same hash code in all circumstances.

Upvotes: 1

Seva Alekseyev
Seva Alekseyev

Reputation: 61380

Should not ever happen. Check for trailing spaces, URL escaping and such.

Upvotes: 1

Related Questions