.NET Hashtable - один и тот же ключ, разные хеши

Могут ли две строки .net иметь разные хеши? У меня есть Hashtable, среди прочего, ключевой «путь». Когда я просматриваю элементы в таблице, чтобы распечатать ее, я вижу, что ключ существует.

Однако при попытке найти соответствующий элемент нет. Отладка предполагает, что строка, которую я ищу, имеет хэш, отличный от того, который я использую в качестве ключа.

Этот код находится в проекте Castle Monorail, использующем Brail в качестве механизма просмотра. Ключ, который я ищу, вставлен строкой Брайля, подобной этой:

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

Затем в этом методе (в настраиваемом IRoutingRule):

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

Ключ печатается в журнале, но функция возвращает ноль. Я не знал, что это может быть проблема даже со строками .net, но я предполагаю, что это какая-то проблема с кодировкой?

Ой, и это работает моно.

По запросу вот соответствующая строка из журнала:

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}

Кроме того, здесь я добавил строку кода над вызовом печати журнала:

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

Загляните в журнал, и вы заметите, что есть две клавиши «пути». Отладчик показывает оба ключа в разных местах таблицы.


person Simon Lindgren    schedule 08.03.2010    source источник


Ответы (5)


Вот ссылка на MSDN на GetHashCode для строк. Если они равны, хэш-коды должны совпадать, однако, если они не равны, они все равно могут иметь один и тот же хеш (какой бы малой ни была эта возможность).

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

Из статьи:

Если два строковых объекта равны, метод GetHashCode возвращает одинаковые значения. Однако не существует уникального значения хэш-кода для каждого уникального строкового значения. Разные строки могут возвращать один и тот же хэш-код.

person kemiller2002    schedule 08.03.2010

Никогда не должно быть. Проверьте конечные пробелы, экранирование URL и т. Д.

person Seva Alekseyev    schedule 08.03.2010

Строки, которые равны согласно StringComparison.Ordinal или, проще говоря, String.Equals, будут иметь один и тот же хэш-код во всех обстоятельствах.

person JaredPar    schedule 08.03.2010

Это делает эта строка [Castle.MonoRail.Framework.Services.DefaultUrlBuilder: 397] ...

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

Если IEqualityComparer удален, проблема исчезнет.

Если это монофоническая ошибка (что, я думаю, должно быть), это все еще проблема с моно 2.10.8.1 (Debian 2.10.8.1-5ubuntu1).

Контрольный пример требует написания и регистрации.

person Patrick McEvoy    schedule 21.03.2013
comment
Эй, никогда не замечал этого ответа. Я уже не помню, в каком проекте возникла эта проблема. Поскольку это был игрушечный проект, я перешел к нему, но так и не решил проблему. Тем не менее, копать было приятно. - person Simon Lindgren; 07.09.2013

Какую версию Mono вы использовали? Это может быть ошибка в Mono, в таком случае отчет об ошибке будет приветствоваться.

Но да, я согласен с Севой, что, вероятно, причина в некоторых конечных пробелах или разделителях или в какой-то другой проблеме кодирования, из-за которой строки отличаются каким-то тонким образом и приводят к разным хешам.

person Monoman    schedule 06.04.2010