2010-08-10 3 views
1

У меня возникли трудности, связанные со всеми rules for the GetHashCode method in MSDN для класса, единственным свойством которого является строка соединения.Реализация GetHashCode на основе строки подключения

Я попытался просто возвращая хэш строки, но возвращает другое значение для строк Provider=Microsoft.ACE.OLEDB.12.0; Data Source=path, Provider=Microsoft.ACE.OLEDB.12.0; Data Source=path; и Data Source=path;Provider=Microsoft.ACE.OLEDB.12.0;, все из которых являются эквивалентными.

Затем я попытался с помощью метода OleDbConnectionStringBuilder.GetHashCode, но это даже не возвращает то же Hashcode в этом случае:

test1.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + 
     PathToExcelFile + ";Extended Properties='Excel 12.0 Macro;HDR=YES;IMEX=1';"; 
test2.ConnectionString = test1.ConnectionString; 

Console.WriteLine(test1.GetHashCode()); 
Console.WriteLine(test2.GetHashCode()); 

Моя цель состоит в том, чтобы использовать свой класс как ключ к словарю, так GetHashCode является важным. Как мне его реализовать?

+0

Вы должны написать синтаксический анализатор. Никакой помощи вообще из рамки вне регулярного выражения. –

ответ

2

Определите каноническую строку соединения и вызовите GetHashCode в этой строке. В этом случае вы можете определить «Provider = Microsoft.ACE.OLEDB.12.0; Источник данных = путь» в качестве вашей канонической формы, а затем вам нужно будет преобразовать все эквивалентные строки соединения в каноническую строку, а затем вызвать GetHashCode.

Тогда возникает вопрос: насколько сложно превратить все эквивалентные строки соединения в одну строку?

0

Очень сложно, если не невозможно, определить, совпадают ли соединения. Единственное предположение, которое вы можете сделать, состоит в том, что если строки равны, строки подключения.

Например, "." может быть равно «localhost». Или localhost может иметь запись файла хостов, переопределяющую его. Некоторым будущим версиям структуры может потребоваться «;» в конце строки .. две версии драйверов могут быть функционально эквивалентными, но вы относитесь к ним по-разному. Там, где вы рисуете линию, это очень шелушащее дело.

Моя точка: Если вы не используете класс, который определяет каждый конкретный компонент строки соединения, у вас нет бизнеса, решающего, равны ли две строки соединения, кроме сравнения строк.

0

Я решил эту проблему на основе входных данных от обоих ответов:

Define каноническую строку подключения

И

Если вы не используете класс, который определяет каждый конкретный компонент строки подключения , у вас нет бизнес, решающий, есть ли два строки подключения равны, за пределами Сравнение строк.

Итак, я создал метод расширения для OleDbConnectionStringBuilder:

public static int GetRealHashCode(this OleDbConnectionStringBuilder target) 
{ 
    int ToReturn = 17; 
    ToReturn *= target.DataSource.TrimEnd(';').GetHashCode(); 
    ToReturn *= target.Provider.TrimEnd(';').GetHashCode(); 
    ToReturn *= target.PersistSecurityInfo.ToString().GetHashCode(); 

    var OrderedKeys = from string key in target.Keys 
       orderby key 
       select key; 
    foreach (string Key in OrderedKeys) 
     ToReturn *= target[Key].GetHashCode(); 

    return ToReturn; 
} 
Смежные вопросы