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

PDF имеет недостаток требования Adobe Reader

, я использую Читатель Foxit в Windows дома и на работе. Намного меньший и очень быстрый для открытия. Очень удобный, когда Вы задаетесь вопросом, что точно a80000326.pdf и почему это забивает Вашу папку документов.

7
задан nawfal 1 November 2013 в 02:42
поделиться

3 ответа

Да, есть - System.Collections.ObjectModel.KeyedCollection .

Это абстрактно, и в структуре нет конкретных производных классов насколько я понимаю, но все, что вам нужно реализовать, это GetKeyForItem , насколько я могу судить. Например, вы можете сделать это с помощью делегата:

public class DelegatingKeyedCollection<TKey, TItem> : System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
{
    private readonly Func<TItem, TKey> keySelector;

    public DelegatingKeyedCollection(Func<TItem, TKey> keySelector)
    {
        this.keySelector = keySelector;
    }

    protected override TKey GetKeyForItem(TItem item)
    {
        return keySelector(item);
    }
}
10
ответ дан 6 December 2019 в 12:52
поделиться

KeyedCollection, как говорит Джон Скит, является очевидным кандидатом.

Несколько случайных замечаний об этом классе:

  • Вы, конечно, захотите, чтобы свойство, которое вы используете в качестве ключа, было доступно только для чтения.

  • Его метод Contains (TItem item) унаследован от Коллекция , и реализуется путем итерации по коллекции. Следовательно, это может быть намного медленнее, чем Contains (TKey key) . Разработчикам слишком легко сделать ошибку, используя неправильную перегрузку, поэтому, возможно, стоит подумать о реализации собственного метода Contains (TItem item) :

     public new bool Contains (TItem item)
    {
     if (item == null) выбросить новое исключение ArgumentNullException ("item");
     return this.Contains(GetKeyForItem(item));
    }
    
  • Unlike an IDictionary, it doesn't have a method TryGetValue. This can be useful and it might be worth implementing your own:

    public bool TryGetValue(TKey key, out TItem item)
    {
     // If the dictionary exists, use it
     if (Dictionary != null) return Dictionary.TryGetValue(key, out item);
     // Else do it the hard way
     if (!this.Contains(key))
     {
     item = default(TItem);
     return false;
     }
     item = this[key];
     return true;
    }
    
  • It doesn't support enumeration of the keys, which can be useful:

    public IEnumerable GetKeys()
    {
     foreach (TItem item in this)
     {
     yield return GetKeyForItem(item);
     }
    }
    
  • Serialization can be inefficient, as it will serialize both its internal list and its internal dictionary. You can get round this if you need to by implementing custom serialization.

4
ответ дан 6 December 2019 в 12:52
поделиться

Use a normal one, and when you set the key value pair, specify the property of the value you are interested in.

That was too easy, I must be misunderstanding your request.

Maybe you wanted to use an arbitrary property later rather than at input time. In that case, I think you would have to use multiple dictionary objects (perhaps tied together in a helper class).

2
ответ дан 6 December 2019 в 12:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: