如何通过组与LINQ的自定义类型 [英] How to group by custom types with linq
问题描述
我有这个类
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查询:
And I want to have a linq query like that :
var grouped = from it in items
group it by it.Coordinate into grp
select grp;
这里提到的MSDN被我认为这是可能的,如果我将改写等于我协调类:
As mentioned here by MSDN I thought this was possible if I would override Equals on my Coordinate class :
使用一个命名的类型,如果你必须通过 查询变量的另一种方法。 创建使用一种特殊的类 自动实现的属性为 项,然后重写Equals 和GetHash code的方法。你也可以 使用结构,在这种情况下,你不这样做 严格要覆盖这些 的方法。欲了解更多信息,请参阅如何 :实现一个不可变的类 具有自动实现的属性。
Use a named type if you must pass the query variable to another method. Create a special class using auto-implemented properties for the keys, and then override the Equals and GetHashCode methods. You can also use a struct, in which case you do not strictly have to override those methods. For more information see How to: Implement an Immutable Class That Has Auto-Implemented Properties
等于实现协调类:
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());
}
有一个超载的GrouBy方法接受一个的IEqualityComparer作为参数,但有使用group子句的相同呢? 难道我做错了什么?有什么想法?
There is an overload to the GrouBy method that takes an IEqualityComparer as a parameter, but is there the equivalent using the group clause? Am I doing something wrong?? Any thoughts?
推荐答案
您已经证明了等于执行,但不GetHash code。您需要同时重写(并以一致的方式)进行分组工作。
You've shown the Equals implementation, but not GetHashCode. You need to override both (and in a consistent way) for grouping to work.
样品GetHash code实现的:
Sample GetHashCode implementation:
public override int GetHashCode()
{
int hash = 23;
hash = hash * 31 + Latitude.GetHashCode();
hash = hash * 31 + Longitude.GetHashCode();
return hash;
}
请注意:在比较浮动
值确切平等永远是很危险的 - 但我至少希望你的单元测试通过,因为他们没有执行任何计算。
Note that comparing float
values for exact equality is always somewhat risky - but I'd at least expect your unit tests to pass, given that they're not performing any calculations.
这篇关于如何通过组与LINQ的自定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!