[英]Collection of Collections VS Dictionary of Collections in C#?
情况:我需要传递一组对象,然后对它们进行分组。 我知道我可以为此使用LINQ。
但是,如果我自己做的话, 让我的方法返回“收藏集VS收藏集字典”之间是否有任何偏好? 我知道Dictionary也是一个集合,但是它引入了key参数。
提前致谢。
总结评论:
如果您想向用户展示内容,并且说您愿意,那么Dictionary
几乎肯定是错误的方法。 Dictionary
没有可预测的顺序。 按照从Dictionary
中检索它们的顺序显示Dictionary
中的Dictionary
是没有意义的。
如果键的顺序与项目的预期顺序匹配,则始终按键值排序的SortedDictionary
或SortedList
可能是合适的。
但是否则,只需使用常规数组/ List
/ Collection
,您就可以在其中手动按照所需的顺序手动放置项目。
您已经发布了一个相当模糊的问题,但让我们继续进行讨论,使其更加具体。 假设您有一个此类的集合:
public class MyItem
{
public string Name { get; set; }
public string Description { get; set; }
public DateTime OrderDate { get; set; }
}
并且您有一个将其分组的方法(以及可选的过滤器,...执行其他操作),如下所示:
public RETURNTYPE ProcessItemGroupedByOrderDate(IEnumerable<MyItem> items);
那应该按OrderDate
属性分组。
您的问题是:
在让我的方法返回“收藏集”与“收藏字典”之间是否有任何偏好? 返回的对象的预期用途是使用For Each语句按组显示。
即RETURNTYPE
应该是
IDictionary<DateTime, ICollection<MyItem>>
或 ICollection<ICollection<MyItem>>
其中ICollection
表示任何合适的集合类型( IEnumerable
, IList
,...)。
我的答案是:让客户决定。 如果您返回分组,则让返回类型为:
IEnumerable<IGrouping<DateTime, MyItem>>
除了一个明显的决定点,即是否需要按照某些标准(如Dictionary所提供的那样)对外部集合进行索引,通常只是每个外部项目需要多少信息。
在频谱的一端,每个外部项目都没有与之关联的元数据。 外部列表中的每个项目只是一个集合,没有标识信息。 例如,如果您按学生所在的宿舍对学生列表进行了分组,那么在遍历列表时,您会知道所有这组学生都属于同一个宿舍,但是您不知道哪个宿舍基于仅在您的列表中。
频谱的中间是带有原始键的字典。 现在,您可以获得每个嵌套列表KeyValuePair Key的信息。 该密钥可能是标识宿舍的某种唯一ID。
频谱的另一端是无限的元数据。 您为外部列表中的项目定义一个类,并且该项目的属性是一个集合:
class Dorm {
public int DormID {get;set;}
public string DormName {get;set;}
public Gender DormPermittedGender {get;set;}
public List<Person> Students {get;set;}
}
class Person {
public string Name {get;set;}
public Gender Gender {get;set;}
public int Age{get;set;}
}
///...
List<Dorm> dorms = db.Dorms.Select(d=>
new Dorm {
DormId = d.Id,
DormName = d.Name,
DormPermittedGender = d.PermittedGender,
Students = d.StudentsResiding
}
)
foreach(Dorm dorm in dorms)
{
foreach(Person student in dorm.Students)
{
Console.Writeline(student.Name + " lives in " + dorm.DormName);
}
}
注意foreach的可读性。 没有神秘的钥匙。
现在,词典实际上可以做到这一点,因为您可以将复杂的对象作为键,但是它的组织性不强。 如果情况需要,强类型对象将更好地表示这种关系。
过度使用列表或字典列表会使代码难以阅读,因为没有自我描述的属性名称。 您遇到了一些旧的代码,并且不得不四处寻找首先分配了Dictionary以确定Key含义的位置,因为您所拥有的只是类型,它是一个不传达语义的int
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.