2013-02-12 3 views
2

У меня есть IDictionary<TKey, TValue>, где TKey - это класс. Могу ли я добавить возможность использования индексатора с String значением вместо TKey?Словарь TKey Indexer Использование строки

public class MyClass { 
    public string Name { get; set; } 
} 

.... 

//dict is a IDictionary<MyClass, object> 
dict.Add(new MyClass { Name = "Foo" }); 

В настоящее время я использую Linq для доступа к значениям по Name, но я предпочел бы что-то вроде этого:

//This call returns the variable I added above 
object value = dict["Foo"]; 

Возможно ли это?

+0

Вы можете реализовать 'IDictionary <,>' в своем классе ..? –

+0

@Simon Я пытался избежать создания своего собственного IDictionary –

ответ

0

Это может быть хороший подход к вашей проблеме, если с помощью Name определить равенство делает смысл для MyClass вообще, а не только в данном конкретном словаре:

public class MyClass 
{ 
    public string Name { get; set; } 
    public override int GetHashCode() 
    { 
     return Name.GetHashCode(); 
    } 
    public override bool Equals(object other) 
    { 
     return this.Name == ((MyClass)other).Name; 
    } 
} 

Тогда ваш словарь просто проиндексированы MyClass объектов. Если у вас есть явное string вместо MyClass Например, вы можете получить значение этого словаря, как это:

dict[new MyClass { Name = "Foo" }] 

Можно также добавить:

public static implicit operator MyClass(string s) 
{ 
    return new MyClass { Name = s }; 
} 

А индекс как:

dict["Foo"] 

Опять же, сделайте это только в том случае, если это имеет смысл для MyClass в целом, а не только для использования в этом словаре. Если это для этого конкретного словаря, попробуйте другое решение.

+0

Спасибо Тим. Я не думал об использовании неявного оператора, и конечный результат был именно тем, что мне нужно. –

+1

@SimonHartcher вы считаете, что это хороший подход для создания (бесполезного) инстанса 'MyClass' каждый раз, когда вам нужно получить доступ к тому, который хранится в словаре? – horgh

+0

@ КонстантинВасильков В моем случае, я делаю. Мне не нужно создавать 'IDictionary' только для этой конкретной проблемы, а влияние кода минимально. Если я чего-то не упускаю, я не вижу большой проблемы с этим. –

3

Вы можете создать свой собственный класс словаря на основе вашего класса.

public class MyClass 
{ 
    public string Name { get; set; } 

    // You may want to implement equality members on your class so that 
    // the dictionary treats the Name value as the key correctly. 
} 

public class MyClassDictionary<TValue> : Dictionary<MyClass, TValue> 
{ 
    public TValue this[string val] 
    { 
     get 
     { 
      return base[Keys.First(x => x.Name == val)]; 
     } 
    } 
} 

Вы можете использовать это, как хотите.

MyClassDictionary<string> instance = new MyClassDictionary<string>(); 

instance.Add(new MyClass() { Name = "testkey" }, "test value"); 

Debug.WriteLine(instance["testkey"]); 
+0

Я пошел с ответом Тима, поскольку мне нужно было только изменить MyClass с его решением. Это решение действительно работает :) –

+0

Не беспокойтесь, неявный оператор также ускользнул от меня как простой ответ:> –

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