PDF имеет недостаток требования Adobe Reader
, я использую Читатель Foxit в Windows дома и на работе. Намного меньший и очень быстрый для открытия. Очень удобный, когда Вы задаетесь вопросом, что точно a80000326.pdf и почему это забивает Вашу папку документов.
Да, есть - 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);
}
}
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.
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).