.net 如何使用linq按自定义类型分组
我有这门课.net 如何使用linq按自定义类型分组,.net,linq,group-by,.net,Linq,Group By,我有这门课 public class Item { public Coordinate coordinate { get; set; } ... ... } 坐标的定义如下: public class Coordinate { public Coordinate(float latitude, float longitude) { Latitude = latitude;
public class Item
{
public Coordinate coordinate { get; set; }
...
...
}
坐标的定义如下:
public class Coordinate
{
public Coordinate(float latitude, float longitude)
{
Latitude = latitude;
Longitude = longitude;
}
public float Latitude { get; private set; }
public float Longitude { get; private set; }
}
我想要一个像这样的linq查询:
var grouped = from it in items
group it by it.Coordinate into grp
select grp;
我认为如果我在坐标类中重写Equals,这是可能的:
如果必须通过
查询变量到另一个方法。
使用创建一个特殊类
自动实现的属性
键,然后覆盖相等项
和GetHashCode方法。你也可以
使用struct,在这种情况下,您不需要
我们必须严格遵守这些规定
方法。有关更多信息,请参见如何
to:实现一个不可变的类
具有自动实现的属性
等于坐标类的实现:
public override bool Equals(object obj)
{
var coord = obj as Coordinate;
if(coord == null) return false;
return (Latitude == coord.Latitude && Longitude == coord.Longitude);
}
尽管如此,我还是无法通过类似的坐标将linq查询分组,因为我的测试失败显示:
[TestMethod]
public void GroupBy_3ItemsWith2DifferentCoordinates_Returns2Groups()
{
var items = new List<Item>
{
new Item {Coordinate = new Coordinate(10, 10)},
new Item {Coordinate = new Coordinate(10, 10)},
new Item {Coordinate = new Coordinate(12, 10)},
};
var grouped = from it in items
group it by it.Coordinate into g
select g;
Assert.AreEqual(2, grouped.Count());
}
[TestMethod]
公共作废分组依据2个不同坐标的项目2个分组()
{
var items=新列表
{
新项目{坐标=新坐标(10,10)},
新项目{坐标=新坐标(10,10)},
新项目{坐标=新坐标(12,10)},
};
var grouped=从项目中的它开始
按它分组,协调成g
选择g;
Assert.AreEqual(2,grouped.Count());
}
Groupby方法有一个重载,该重载将IEqualityComparer作为参数,但是否有使用group子句的等价项?
我做错什么了吗??有什么想法吗?您已经展示了Equals实现,但没有展示GetHashCode。为了使分组工作,您需要同时覆盖这两个选项(并且以一致的方式) GetHashCode实现示例:
public override int GetHashCode()
{
int hash = 23;
hash = hash * 31 + Latitude.GetHashCode();
hash = hash * 31 + Longitude.GetHashCode();
return hash;
}
请注意,比较float
值以获得精确的相等性总是有一定的风险——但我至少希望您的单元测试能够通过,因为它们没有执行任何计算
格劳比号超载了
方法,该方法接受IEqualityComparer
作为参数,但是否存在
使用group子句是否等效
如果您只需要一个快速的内联解决方案,并且不担心键入键的确切类型,则始终可以按匿名类型分组:
var grouped =
from it in items
group it by new {it.Coordinate.Latitude, it.Coordinate.Longitude};
刚试过,这就是我错过的。非常感谢:)public override int GetHashCode(){return((int)Latitude*100)^((int)Longitude*100);}如果哈希代码就是这样做的,那么应该确保相等代码与之匹配-它们应该彼此一致。Latitude.GetHashCode()^Longitude.GetHashCode()在反转纬度和经度时给出相同的结果。所以这不是一个好的解决方案,因为我想确保coord(x,y)!=坐标(y,x);您的代码可以工作,因为操作顺序很重要。感谢您的精确性,这很有帮助:)我知道这个解决方案,但您不会将坐标类作为键,而是一个匿名类型。