В основном вам нужно решить, могут ли пользователи класса быть смущены тем фактом, что они не могут, например, сделать:
for(int i=0; i=< myCollection.Count; i++)
{
... myCollection[i] ...
}
хотя они могут, конечно, использовать foreach или использовать приведение:
for(int i=0; i=< myCollection.Count; i++)
{
... ((Collection<MyType>)myCollection)[i] ...
}
Это не легкое решение, так как оно может легко привести к появлению гейзенгов. Я решил разрешить это в одном из моих приложений, где доступ от пользователей класса был почти исключительно по ключу.
Я не уверен, что сделал бы это для общей библиотеки классов, хотя: в общем, я бы избегал выставлять KeyedCollection в публичном API: вместо этого я бы выставлял IList в публичном API, и потребителям API, которому необходим доступ по ключу, может определить свой собственный внутренний KeyedCollection с помощью конструктора, который принимает IEnumerable и заполняет коллекцию им. Это означает, что вы можете легко создать новую коллекцию KeyedCollection из списка, полученного из API.
Что касается сериализации, существует также проблема с производительностью , о которой я сообщил в Microsoft Connect : KeyedCollection поддерживает внутренний словарь и список, а также сериализует оба - достаточно сериализовать список как словарь может быть легко воссоздан при десериализации.
По этой причине, а также из-за ошибки XmlSerialization, я бы рекомендовал вам не сериализовать KeyedCollection - вместо этого только сериализуйте список KeyedCollection.Items.
Мне не нравится предложение обернуть ваш ключ int в другой тип . Мне кажется неправильным добавлять сложность просто так, чтобы тип мог использоваться как элемент в KeyedCollection. Я бы использовал строковый ключ (ToString) вместо того, чтобы делать это - это скорее похоже на класс VB6 Collection.
FWIW, я задал тот же вопрос некоторое время назад на форумах MSDN. Есть ответ от члена команды FxCop, но нет убедительных рекомендаций.