我正在使用linq查询集合,并datetime使用以下代码按属性对数据进行分组:
var querty = from post in ds.Appointments
group post by new
{
Year = post.DateOfVisit.Year,
Month = post.DateOfVisit.Month
};
Run Code Online (Sandbox Code Playgroud)
当使用匿名类型时,一切都很好.但是,如果我定义自己的类
class YearMonth
{
public int Year;
public string Month;
public YearMonth(int year, int month)
{
Year = year;
Month = month;
}
public override string ToString()
{
return string.Format("{0}-{1}",Year,Month);
}
}
Run Code Online (Sandbox Code Playgroud)
并相应地修改我的查询
var querty = from post in ds.Appointments
group post by new YearMonth(post.DateOfVisit.Year,
post.DateOfVisit.Month);
Run Code Online (Sandbox Code Playgroud)
然后分组不起作用,我得到一个简单的对象列表.为什么?
正如schglurps已经说了,你要重写GetHashCode和Equals,因为GroupBy方法(和其他人)依靠这些机构.
该GroupBy方法基于它所分组的对象的哈希码(和相等)创建最终组.
因此,对于序列中的每个项目,它会检查是否已有一个具有相同哈希码的组,然后检查该项是否等于该组的键.如果没有匹配的组,则会创建一个新组.
在您的情况下,由于您没有覆盖GetHashCode,每个实例YearMonth将具有不同的哈希代码(冲突旁边),因此每个项目将导致创建一个新组.
只需看看相关的参考资料.
这是一个示例实现:
public class YearMonth : IEquatable<YearMonth>
{
public readonly int Year;
public readonly int Month;
public YearMonth(int year, int month)
{
Year = year;
Month = month;
}
public override string ToString()
{
return string.Format("{0}-{1}", Year, Month);
}
public bool Equals(YearMonth other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Month == other.Month && Year == other.Year;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((YearMonth)obj);
}
public override int GetHashCode()
{
unchecked
{
return (Month * 397) ^ Year;
}
}
public static bool operator ==(YearMonth left, YearMonth right)
{
return Equals(left, right);
}
public static bool operator !=(YearMonth left, YearMonth right)
{
return !Equals(left, right);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |