J'ai cette classeComment regrouper par types personnalisés avec LINQ
public class Item
{
public Coordinate coordinate { get; set; }
...
...
}
Avec coordonnées étant définir comme ceci:
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; }
}
Et je veux avoir une requête LINQ comme ça:
var grouped = from it in items
group it by it.Coordinate into grp
select grp;
As mentioned here by MSDN Je pensais que c'était possible si je devais remplacer Equals sur ma classe de coordonnées:
Utilisez un type nommé si vous devez transmettre la variable de requête à une autre méthode. Créez une classe spéciale à l'aide des propriétés implémentées automatiquement pour les clés , puis remplacez les méthodes Equals et GetHashCode. Vous pouvez également utiliser une struct, , auquel cas vous n'avez pas besoin de surcharger les méthodes . Pour plus d'informations, voir Comment : implémenter une classe Immuable Ce a des propriétés Mis en œuvre automatique
Equals mise en œuvre pour coordonner la classe:
public override bool Equals(object obj)
{
var coord = obj as Coordinate;
if(coord == null) return false;
return (Latitude == coord.Latitude && Longitude == coord.Longitude);
}
encore je ne peux pas obtenir ma requête LINQ to groupe par des coordonnées similaires , comme mon défaut test de montre:
[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());
}
Il y a une surcharge la méthode GrouBy qui prend un IEqualityComparer en paramètre, mais y a-t-il l'équivalent en utilisant la clause group? Est-ce que je fais quelque chose de mal ?? Des pensées?
juste essayé, c'est ce que je manquait.Grand merci :) public override int GetHashCode() { return ((int) Latitude * 100)^((int) Longitude * 100); } –
Si c'est ce que fait votre code de hachage, vous devez vous assurer que votre code d'égalité correspond à celui-ci - ils doivent être cohérents les uns avec les autres. –
Latitude.GetHashCode()^Longitude.GetHashCode() donne les mêmes résultats lors de l'inversion de la latitude et de la longitude. Donc ce n'était pas une bonne solution car je veux m'assurer que coord (x, y)! = Coord (y, x); Votre code fonctionne puisque l'ordre des opérations est important. Merci pour la précision, qui a aidé :) –