Словарь Inherits (TKey, TValue) не может быть без учета регистра - PullRequest
2 голосов
/ 06 февраля 2012

Пожалуйста, мне нужна помощь.У меня есть свой собственный класс:

Public Class SerializableDictionary(Of TKey, TValue)
    Inherits Dictionary(Of TKey, TValue)
    Implements IXmlSerializable

....

End Class

Но метод ContainsKey чувствителен к регистру.Я пробую все, мне нужно сравнить строку с учетом регистра.Я думаю изменить CurrentCulture в потоке, я не нашел, как.

Ответы [ 2 ]

4 голосов
/ 06 февраля 2012

Он чувствителен только к регистру, если вы используете регистр с учетом регистра. Вам нужно передать нечувствительный компаратор базовому конструктору. В C # это будет что-то вроде:

public class SerializableDictionay<TKey, TValue>
    : Dictionary<TKey,TValue>, IXmlSerializable
{
    public SerializableDictionay() : base(GetComparer()) { }

    static IEqualityComparer<TKey> GetComparer() {
        if(typeof(TKey) == typeof(string)) {
            // just one of the possibilities
            return (IEqualityComparer<TKey>)(object)
                  StringComparer.InvariantCultureIgnoreCase;
        }
        return EqualityComparer<TKey>.Default;
    }
}

или намного лучше ИМО, пусть звонящий решит:

public class SerializableDictionay<TKey, TValue>
    : Dictionary<TKey,TValue>, IXmlSerializable
{
    public SerializableDictionay() : base() {}
    public SerializableDictionay(IEqualityComparer<TKey> comparer)
              : base(comparer) {}
}

(и пусть инициализаторы вызывающей стороны указывают желаемый строковый компаратор)

2 голосов
/ 06 февраля 2012

Наследование от Dictionary(Of TKey, TValue), как правило, неправильно: обычно составлять коллекцию лучше, чем наследовать от нее.

Однако выв основном нужно убедиться, что в словаре используется регистр без учета регистра - что вы делаете, передавая что-то вроде StringComparer.OrdinalIgnoreCase в соответствующую перегрузку конструктора для Dictionary.Тщательно продумайте, в какой культуре вы хотите выполнить сравнение, если оно есть.

Вы можете сделать это либо в существующем классе, написав конструктор, который вызывает MyBase.New(StringComparer.OrdinalIgnoreCase):

Public Class SerializableDictionary(Of TValue)
    Inherits Dictionary(Of String, TValue)
    Implements IXmlSerializable

    Public Sub New()
        MyBase.New(StringComparer.OrdinalIgnoreCase)
    End Sub

End Class

Обратите внимание, что исправление для использования string типа ключа - было бы немного необычно для него "знать" об одном конкретном типе ключа отдельно, но все же быть универсальным.

Или вы можете просто передать егов конструктор как обычно, если вы идете с составным маршрутом.

...