2011-10-24 9 views
5

Böyle bir şey yapmak istiyorum:Bütünleşikler üzerinde birleştirici operatörü CompareTo zincirleme için kullanabilir miyim?

public override int CompareTo (Foo rhs) 
{ 
    return Bar.CompareTo(rhs.Bar) ?? 
      Baz.CompareTo(rhs.Baz) ?? 
      Fuz.CompareTo(rhs.Fuz) ?? 0; 
} 

Bu yazılı olarak çalışmaz; çalışmasını sağlamak için bazı en az geçici çözüm var mı? Temel olarak sıfır olmayana (veya zincirin sonuna) kadar 0'ın zincirlenmesini istiyorum.

+0

kullanın. –

+0

@DJ 'CompareTo' sıralama ile ilgili; Bu oldukça yaygın, aslında - örneğin, Soyadı ile sıralama - Eğer aynı ise, sonra FirstName göre sıralama, daha sonra hala eşit, bazı benzersiz tanımlayıcı (örneğin, veritabanı kimliği) göre sıralayın. –

+0

@Marc İlginç, Daha önce buna maruz kalmadım. CompareTo'nun IComparable sınıfının bir parçası olduğunu görüyorum. Bir bakış açısı kazanmak için daha fazla okumak zorundayım. Teşekkürler –

cevap

2

için çalışır

int delta = Bar.CompareTo(rhs.Bar); 
if(delta == 0) delta = Baz.CompareTo(rhs.Baz); 
if(delta == 0) delta = Fuz.CompareTo(rhs.Fuz); 
return delta; 
+0

Ugh. Bu gibi çözümler, küresel işlevlere sahip olamayacağımızın ne kadar berbat olduğunu göstermektedir. –

+0

Çok fazla kullanılırsa, her zaman bir genişletme işlevine yerleştirilebilir. – driis

+0

Neyin bir uzantısı? Int32? Bu mümkün mü? –

2

Temelde hayır, ama güzel olurdu, (IIRC, Jon, derinlikte C# ile benzer bir fikirden bahsetmişti). Muhtemelen conditionals zincir olabilir, ama sadece kullanma eğiliminde: Pek değil, ?? sadece dilin tarafından desteklenmiyor boş değerler (referans türleri veya null yapılar)

int i; 

i = Bar.CompareTo(rhs.Bar); 
if (i != 0) return i; 

i = Baz.CompareTo(rhs.Baz); 
if (i != 0) return i; 

i = Fuz.CompareTo(rhs.Fuz); 
if (i != 0) return i; 

return 0; 
2

. Ama bu gibi küçük bir yardımcı yazabilirsiniz: kısa devre gerekli değilse

public override int CompareTo (Foo rhs) 
{ 
    return FirstNonZeroValue(
     () => Bar.CompareTo(rhs.Bar), 
     () => Baz.CompareTo(rhs.Baz), 
     () => Fuz.CompareTo(rhs.Fuz)); 
} 

private int FirstNonZeroValue(params Func<int>[] comparisons) 
{ 
    return comparisons.Select(x => x()).FirstOrDefault(x => x != 0); 
} 
0

, bazı ikili aritmetik yapabilirsiniz. It is not required that the Compare results must be -1, 0, or 1, but that they must be < 0, = 0, > 0. Bu nedenle n'nin öncelikli olduğu bir katsayı olarak 2^n kullanarak, CompareTo sonuçlarını toplayabilir ve gerektiğinde bir sayı> 0 veya < 0 alabilirsiniz.

Yani, Sorunuzun cevabını bilmiyorum, ama üç değer dönüş değerini belirlemek için kullanılabilir ise, size sınıf yeniden tasarlama düşünebilirsiniz

return 4 * Bar.CompareTo(rhs.Bar) 
    + 2 * Baz.CompareTo(rhs.Baz) 
    + 1 * Fuz.CompareTo(rhs.Fuz); 
İlgili konular