Я хочу иметь возможность искать значения по ключу в тех же случаях, а в других случаях выполнять итерацию по коллекции.
Ранее я делал это:
public class Company
{
public string Name { get; set; }
public ICollection<Department> Departments { get; set; }
}
public class Department
{
public string Name { get; set; } //display name
public string UniqueName { get; set; } //like a code value
public bool IsSelected { get; set; }
}
foreach(var d in someCompany.Departments) ...
var departments = someCompany.Departments.Select( d => some projection stuff ...
Теперь у меня есть несколько мест, которые мне также нужно перебрать в какой-то другой коллекции, например, списки флажков с соответствующими строками для UniqueName, поэтому для большей эффективности я изменил объявление Departments на IDictionary, но это делает другие варианты использования более громоздким, всегда требуя от меня углубиться в стоимость или ценности. Таким образом, теперь свойство Departments больше не является коллекцией классов Department, а представляет собой коллекцию пар KeyValue.
foreach(ListItem item in someCheckBoxes.Items)
{
someCompany.Departments[item.Value].Selected = true;
}
foreach(var d in someCompany.Departments.Values) ...
var departments = someCompany.Departments.Values.Select( d => some projection stuff ...
Мне также не важно преобразовывать списки в IDictionary или добавлять KeyValue всякий раз, когда я инициализирую эти списки.
В идеале у меня должна быть коллекция, которая ведет себя как ICollection, но также имеет оператор индекса и содержит функцию, которая обеспечивает внутренний доступ к словарю.
ИЛИ у меня было бы два свойства, которые так синхронизируются:
public Company(string uniqueName, string name, ICollection<Department> departments)
{
Name = name;
UniqueName = uniqueName;
DepartmentsByUniqueName = departments.ToDictionary<Department, string>(p => p.UniqueName);
}
public IDictionary<string,Department> DepartmentsByUniqueName { get; set;}
public ICollection<Department> Departments { get { return DepartmentsByUniqueName.Values; } }
public void AddDepartment(Department department)
{
DepartmentsByUniqueName.Add(department,department.UniqueName)
}
Проблема здесь в том, что кто-то может получить коллекцию Values через свойство Departments и добавить / удалить элементы к нему, не осознавая, что они действительно должны быть добавлены в словарь вместо этого (реализация set не решает эту проблему, потому что они получают собрание через get, а затем может добавлять элементы к нему.)
Попытка не изобретать слишком много кода, но наследование от словаря автоматически делает его наследником IEnumerable. Даже если я сделаю явную реализацию интерфейса, могут возникнуть проблемы, если пользователь приведёт его к этому базовому интерфейсу.
Так что, по сути, я хочу класс, который реализует IEnumerable, но также имеет операторы Contains и [], которые для большей эффективности используют словарь.
ИЛИ сможете создать дополнительное свойство словаря DepartmentByUniqueName, которое будет синхронизировано с коллекцией Departments.