我希望能够在相同情况下通过键查看值,并在其他情况下遍历集合。IDictionary是IEnumerable <ValueType>而不是KeyValue?
以前我是这样做的:
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字符串,所以它是有效的,我改变了列出将部门声明为IDictionary,但这会使其他用例更加繁琐,总是要求我钻取一个Value或Values。因此,现在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,但也有一个索引操作符并包含一个内部访问字典的函数。
OR我有两个属性,像这样,那留在同步:
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)
}
这里的问题是,有人可以通过部门属性获取值集合,并添加/删除项目到它,而不是reallizing他们确实需要被添加到字典中(实现集并不能解决这个问题,因为他们通过获取来得到回调,然后可以添加项)。
尝试不重新创建太多的代码,而是继承从Dictionary自动使它继承IEnumerable。即使我做了明确的接口实现,如果用户将其转换为基本接口,也会出现问题。
所以基本上我想要一个实现IEnumerable的类,但也有一个Contains和[]运算符,它们在内部利用字典来提高效率。
或者能够创建与Department部门集合保持同步的额外DepartmentByUniqueName字典属性。
为什么不直接使用字典的'Values'属性时需要迭代? – 2012-01-27 22:28:37
因为该属性称为Departments,而不是DepartmentKeyValuePairs。在每个用例中总是访问.Value或.Values时,它的语义意义不大,因为实际上字典只是一个索引。总是将密钥传递给.Add。也是不必要的。相比之下,KeyedCollection非常棒,因为您将该逻辑烘焙到集合中,每次添加项目时都会使用该属性作为Key。而不是ICollection它是一个ICollection 。 –
AaronLS
2012-02-02 22:50:09