2014-09-15 2 views
3

У меня проблема. Кажется, я не могу оборачивать голову. Я создаю класс для хранения словаря предметов, которые имеют общие типы. Проблема, с которой я столкнулся, необходима, чтобы заставить этот словарь быть InvariantCultureIgnoreCase, если Тип индекса - это строка.Общее сравнение словарей

Например:

public class Cache<TIndex, TItem> 
{ 
    protected IDictionary<TIndex, TItem> _cache { get; set; } 

    public Cache() 
    { 
     this._cache = new Dictionary<TIndex, TItem>(); 
    } 

    public bool Exists(TIndex index) 
    { 
     if (!_cache.ContainsKey(index)) 
     { 
      //....do other stuff here 
      this._cache.Add(databaseResult.Key, databaseResult.Value); 
      return false; 
     } 
     return true; 
    } 
} 

Итак, первая проблема имеет дело со строками, которые имели различную капитализацию; Я решил это, заставив данные быть в верхнем регистре. Теперь, однако, я обнаружил, что есть некоторые символы, которые являются специфическими для культуры, поэтому без переключения инвариантной культуры ContainsKey вернет false.

Я пробовал создать новый IEqualityComparer, но это никогда не срабатывает. Есть идеи?

+1

Код, который вы показали, ничего не показывает о 'IEqualityComparer'. Я подозреваю, что вам просто нужно разрешить 'IEqualityComparer ' быть переданным в конструктор и предоставленным в словарь. –

+0

«Я попытался создать новый IEquityComparer, но это никогда не срабатывает». Вы только что создали его? Или вы действительно назначили его в словарь? – Tim

+0

Я пробовал это раньше; Я назначил его в конструкторе, но он никогда не срабатывает. – brenton

ответ

5

Пожалуйста, попробуйте следующее:

public Cache() 
{ 
    if (typeof(TIndex) == typeof(string)) 
    { 
     this._cache = new Dictionary<TIndex, TItem>((IEqualityComparer<TIndex>)StringComparer.InvariantCultureIgnoreCase); 
    } 
    else 
    { 
     this._cache = new Dictionary<TIndex, TItem>(); 
    } 
} 

Или (с тройным оператором):

public Cache() 
{ 
    this._cache = typeof(TIndex) == typeof(string) 
       ? new Dictionary<TIndex, TItem>((IEqualityComparer<TIndex>)StringComparer.InvariantCultureIgnoreCase) 
       : new Dictionary<TIndex, TItem>(); 
} 

Или (очень коротким, как это было предложено @Rawling):

public Cache() 
{ 
    this._cache = new Dictionary<TIndex, TItem>(StringComparer.InvariantCultureIgnoreCase as IEqualityComparer<TIndex>); 
} 
+0

Это выглядит многообещающим. Я дам вам знать, если это сработает. – brenton

+2

Лучше перед редактированием превратить его в трехмерное выражение. – Mephy

+0

Мой первый тест состоял в том, чтобы проверить, что он проигнорировал случай; это не так. К сожалению, это означает, что он не применяет StringComparer (но он добавляет правильный IEqulaityComparer) – brenton

1

Вот полностью функциональную версию того, что я ДУМАЮ, о котором вы просите (мне пришлось добавить функцию Set, иначе она будет основана на вашем собственном коде). Это, как показывает проверка if/Console.WriteLine, игнорируя регистр. Если это не то, что вы ищете, уточните свой вопрос.

class Program 
{ 
    static void Main(string[] args) 
    { 

     Cache<string, string> stringCache = new Cache<string, string>(); 

     stringCache.Set("A String Index", "A String Item"); 

     if (stringCache.Exists("A String Index")) 
      Console.WriteLine("Title Case exists"); 

     if (stringCache.Exists("A STRING INDEX")) 
      Console.WriteLine("All Caps Exists"); 

     if (stringCache.Exists("a string index")) 
      Console.WriteLine("All Lowercase Exists"); 
    } 
} 

class Cache<TIndex, TItem> 
{ 
    private IDictionary<TIndex, TItem> _cache { get; set; } 

    public Cache() 
    { 
     if (typeof(TIndex) == typeof(string)) 
     { 
      _cache = new Dictionary<TIndex, TItem>((IEqualityComparer<TIndex>)StringComparer.InvariantCultureIgnoreCase); 
     } 
     else 
     { 
      _cache = new Dictionary<TIndex, TItem>(); 
     } 
    } 

    public void Set(TIndex index, TItem item) 
    { 
     _cache[index] = item; 
    } 

    public bool Exists(TIndex index) 
    { 
     if (!_cache.ContainsKey(index)) 
     { 
      return false; 
     } 
     return true; 
    } 

} 
+0

Это действительно дает результаты, которые я ожидаю; однако по какой-то причине он не работает в моем текущем контексте. Я отлаживаю, чтобы узнать, какие возможные различия. – brenton

Смежные вопросы