c# – 在linq分组查询中使用严格类型

前端之家收集整理的这篇文章主要介绍了c# – 在linq分组查询中使用严格类型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用 linq查询集合,并使用以下代码通过datetime属性对数据进行分组:
  1. var querty = from post in ds.Appointments
  2. group post by new
  3. {
  4. Year = post.DateOfVisit.Year,Month = post.DateOfVisit.Month
  5. };

当使用匿名类型时,一切都很好.但是,如果我定义自己的类

  1. class YearMonth
  2. {
  3. public int Year;
  4. public string Month;
  5.  
  6. public YearMonth(int year,int month)
  7. {
  8. Year = year;
  9. Month = month;
  10. }
  11.  
  12. public override string ToString()
  13. {
  14. return string.Format("{0}-{1}",Year,Month);
  15. }
  16. }

并相应地修改我的查询

  1. var querty = from post in ds.Appointments
  2. group post by new YearMonth(post.DateOfVisit.Year,post.DateOfVisit.Month);

然后分组不起作用,我得到一个简单的对象列表.为什么?

解决方法

正如schglurps已经说过的那样,你必须覆盖GetHashCode和Equals,因为GroupBy方法(以及其他方法)依赖于这些.

GroupBy方法基于它所分组的对象的哈希码(和相等)来创建最终组.

因此,对于序列中的每个项目,它会检查是否已有一个具有相同哈希码的组,然后检查该项是否等于该组的键.如果没有匹配的组,则会创建一个新组.

在您的情况下,由于您不重写GetHashCode,因此YearMonth的每个实例都将具有不同的哈希代码(冲突旁边),因此每个项目将导致创建一个新组.

只需看看相关的reference source.

这是一个示例实现:

  1. public class YearMonth : IEquatable<YearMonth>
  2. {
  3. public readonly int Year;
  4. public readonly int Month;
  5.  
  6. public YearMonth(int year,Month);
  7. }
  8.  
  9. public bool Equals(YearMonth other)
  10. {
  11. if (ReferenceEquals(null,other)) return false;
  12. if (ReferenceEquals(this,other)) return true;
  13. return Month == other.Month && Year == other.Year;
  14. }
  15.  
  16. public override bool Equals(object obj)
  17. {
  18. if (ReferenceEquals(null,obj)) return false;
  19. if (ReferenceEquals(this,obj)) return true;
  20. if (obj.GetType() != this.GetType()) return false;
  21. return Equals((YearMonth)obj);
  22. }
  23.  
  24. public override int GetHashCode()
  25. {
  26. unchecked
  27. {
  28. return (Month * 397) ^ Year;
  29. }
  30. }
  31.  
  32. public static bool operator ==(YearMonth left,YearMonth right)
  33. {
  34. return Equals(left,right);
  35. }
  36.  
  37. public static bool operator !=(YearMonth left,YearMonth right)
  38. {
  39. return !Equals(left,right);
  40. }
  41. }

猜你在找的C#相关文章