2011-11-29 4 views
10

J'ai deux listes voir ci-dessous ..... résultat REVIENT aussi videIntersection entre deux listes ne fonctionne pas

List<Pay>olist = new List<Pay>(); 
List<Pay> nlist = new List<Pay>(); 
Pay oldpay = new Pay() 
{ 
    EventId = 1, 
    Number = 123,       
    Amount = 1 
}; 

olist.Add(oldpay); 
Pay newpay = new Pay() 
{ 
    EventId = 1, 
    Number = 123,       
    Amount = 100 
}; 
nlist.Add(newpay); 
var Result = nlist.Intersect(olist); 

aucun indice pourquoi?

+0

En supposant que l'égalité de paiement est EventID, Number, AND Amount, il n'y a rien de commun dans ces deux listes et donc rien ne se croise. En d'autres termes, vous n'avez pas défini l'égalité ici. –

+0

Que voulez-vous dire n'a pas défini l'égalité ici? seul élément différent est Amount = 100 – user570715

+0

Il n'y a rien dans la question qui indique que _why_ 'oldpay' devrait être égal à' newpay'. –

Répondre

21

Vous devez remplacer les Equals et GetHashCode méthodes dans votre classe Pay, sinon Intersect ne sait pas quand 2 cas sont considérés comme égaux. Comment pourrait-il deviner que c'est le EventId qui détermine l'égalité? oldPay et newPay sont des instances différentes, donc par défaut, elles ne sont pas considérées comme égales.

Vous pouvez remplacer les méthodes Pay comme ceci:

public override int GetHashCode() 
{ 
    return this.EventId; 
} 

public override bool Equals(object other) 
{ 
    if (other is Pay) 
     return ((Pay)other).EventId == this.EventId; 
    return false; 
} 

Une autre option consiste à mettre en œuvre un IEqualityComparer<Pay> et le transmettre comme paramètre à Intersect:

public class PayComparer : IEqualityComparer<Pay> 
{ 
    public bool Equals(Pay x, Pay y) 
    { 
     if (x == y) // same instance or both null 
      return true; 
     if (x == null || y == null) // either one is null but not both 
      return false; 

     return x.EventId == y.EventId; 
    } 


    public int GetHashCode(Pay pay) 
    { 
     return pay != null ? pay.EventId : 0; 
    } 
} 

... 

var Result = nlist.Intersect(olist, new PayComparer()); 
+2

ou vous pouvez écrire votre propre comparateur: http://msdn.microsoft.com/en-us/library/234b841s.aspx – mydogisbox

+0

@mydogisbox, oui, j'étais en train d'éditer ma réponse pour le mentionner quand vous avez commenté;) –

+0

Ou vous pouvez faire en sorte que 'Pay' tape' 'struct' pour que cela soit fait pour vous, bien que l'implémentation par défaut soit lente car elle utilise la réflexion. – Gebb

0

Intersect est probablement seulement ajouter des objets lorsque la même instance de Pay est dans les deux List. Comme oldPay et newPay sont instanciés, ils sont considérés comme non égaux. La méthode Equals utilise la méthode Equals pour comparer des objets. Si vous ne le remplacez pas, il conserve le même comportement que la classe Object: renvoyer true uniquement si les deux sont la même instance de l'objet. Vous devez remplacer la méthode Equals dans Pay.

//in the Pay class 
    public override bool Equals(Object o) { 
     Pay pay = o as Pay; 
     if (pay == null) return false; 
     // you haven't said if Number should be included in the comparation 
     return EventId == pay.EventId; // && Number == pay.Number; (if applies) 
    } 
0

Les objets sont des types de référence. Lorsque vous créez deux objets, vous avez deux références uniques. La seule façon qu'ils jamais être égaux est si vous avez:

object a = new object(); 
object b = a; 

Dans ce cas, (a == b) est vrai. Lire sur reference vs value types et objects

Et pour résoudre votre problème, surchargent equals et GetHashCode, comme l'a souligné Thomas Levesque sur.

Questions connexes