如何通过组与LINQ的自定义类型自定义、类型、LINQ

2023-09-03 16:56:20 作者:放肆的笑╮是我仅剩的骄傲

我有这个类

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.

 
精彩推荐
图片推荐