2016-03-20 36 views
0

2 tane ana liste var. Alt nesne, üst sınıfın bir özelliğiyle karşılaştırmak istediğim fazladan bir özelliğe sahiptir. Burada Çocuğun bir listesini ebeveynin listesine göre belirli bir değere göre karşılaştırın

örnek

public class Parent 
{ 
    public int X { get; set; } 
} 

public class Child : Parent 
{ 
    public int Y { get; set; } 
} 

public class ClassXCompare : IEqualityComparer<Parent> 
{ 
    public bool Equals(Parent x, Parent y) 
    { 
     var child = (Child)y; 
     return x.X == child.Y; 
    } 

    public int GetHashCode(Parent parent) 
    { 
     int parentXhash = parent.X.GetHashCode(); 
     // Calculate the hash code for the product. 
     return parentXhash ; 
    } 
} 

ve ben aşağıdakileri sınamak eğer şimdi, her zaman

var parentList= new List<Parent> 
     { 
      new Parent {X = 5}, 
      new Parent {X = 6} 
     }; 
     var childList= new List<Child> 
     { 
      new Child {Y = 5}, 
      new Child {Y = 6} 
     }; 
     var compare = new ClassXCompare(); 
     var diff = parentList.Except(childList, compare); 
     Assert.IsTrue(!diff.Any()); // Fail ??? 

benim konu GetHashCode bulunan düşünüyorum fonksiyon

Herhangi başarısız fikir bu nasıl çözülür?

GetHashCode hem öğeler için aynı değeri döndürür keşke sadece adı verilecek Seti/Dictionary

+0

'y' her zaman bir 'Child' içinde 'var child = (Child) y;'? Ve her durumda, lütfen, "her zaman başarısız" (istisna, yanlış sonuç ...) ile tam olarak ne demek istediğini açıklığa kavuşturun. –

+0

Evet y her zaman bir çocuk, istisna yoktur, ** var diff = parentList.Except (childList, karşılaştırın); ** boş dönmelidir, ancak – Maro

cevap

2

Bu gerçekten korkunç bir tasarımdır. Karşılaştırıcıdaki belirli tiplere yazma ihtiyacı, herhangi bir sıkıntıya neden olmaz. Bununla birlikte, aşağıdaki kod geçmektedir. Bununla birlikte, aşağıdaki kod geçer. Farklı bir döküm yöntemini, boş çekleri ve listelerin sıra dışı sırasını not edin.

Sorun, Çocuk örneklerinin X ayarlamaması ve Except yönteminin değerleri Eşitlere geçirdiği sırasının "x" nin "y" değil Çocuk olması anlamına gelmesiydi.

Bu "iş" olabilir, ancak tasarımınızı yeniden gözden geçirmeniz gerekir.

public class Parent 
{ 
    public int X { get; set; } 
} 

public class Child : Parent 
{ 
    public int Y { get; set; } 
} 

public class ClassXCompare : IEqualityComparer<Parent> 
{ 
    public bool Equals(Parent x, Parent y) 
    { 
     var child = y as Child; 

     return child != null && x.X == child.Y; 
    } 

    public int GetHashCode(Parent parent) 
    { 
     var c = parent as Child; 
     if (c == null) 
      return parent.X.GetHashCode(); 
     else 
      return c.Y.GetHashCode(); 
    } 
} 

[TestClass] 
public class UnitTest1 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     var parentList = new List<Parent> 
      { 
        new Parent {X = 5}, 
        new Parent {X = 6} 
      }; 
     var childList = new List<Child> 
      { 
        new Child {Y = 5}, 
        new Child {Y = 6} 
      }; 
     var compare = new ClassXCompare(); 
     var diff = childList.Except(parentList, compare); 
     Assert.IsTrue(!diff.Any()); // Fail ???  
    } 
} 
+0

sayesinde teşekkürler, tasarım hakkında hemfikirim, bu yüzden ben Soruma göre, şu ki tasarımı değiştirmek için hiçbir yetkim yok.Bu yüzden bunu uygulamak zorundayım :-(tekrar teşekkür ederim – Maro

+0

yeterince adil yapacak, her zaman böyle değil :) – AndyPook

+0

Teşekkürler Andy, cevabınızı işaretledim, benzer bir durumda çünkü bu soruyu yeniden soracağım 2 çift karşılaştırın ama her zaman yanlış olsun, ama bu başka bir soru – Maro

0

Eşittir (Bu sorunun sürümü basitleştirilmiş bir uygulama tasarımını görmezden Lütfen) - bakınız General advice and guidelines on how to properly override object.GetHashCode(). Birden çocuk sınıfları işlemek için varsa çok uzatılabilir olmasa

public class ClassXCompare : IEqualityComparer<Parent> 
{ 
    public bool Equals(Parent x, Parent y) 
    { 
     var child = (Child)y; 
     return x.X == child.Y; 
    } 

    public int GetHashCode(Parent parent) 
    { 
     var child = parent as Child; 
     return child == null ? 
      parent.X : child.Y. 
    } 
} 

: bunu düzeltmek için en basit yolu, çocuk değeri varsa HashCode hesaplamak için kullanılan böyle bir şey, kullanmaktır.

Bazı özel generic IEqualityComparer dışındaki birden çok alt dersi işlemenin kolay bir yolu olduğundan ve hatta bunu biraz kısaltmayacağından emin değilsiniz.

P.S. Ayrıca, ikinci parametrenin her zaman bir Child olacağından emin değilim (bu standardın kapsamı olduğundan kuşku duymakla birlikte, bu özel kullanımdaki geçerli uygulama uygun bir şekilde çalışıyor gibi görünüyor), bu nedenle IEqualityComparer'u daha da hassaslaştırmanız gerekebilir. parametrelerin sırası.