2011-01-31 18 views
8

Ben sıralama için genel bir nesne karşılaştırıcısı yazmaya çalışıyorum, ama kıyaslıyor değerlerden biri null nerede örneğini ele vermez fark etmiş. Bir nesne boş olduğunda, boş dizeyle aynı davranmasını istiyorum. Ben String.Empty boş değerler ayarlama denedim ama sonra ben üzerinde CompareTo() çağrılırken "Nesne türü String olmalı" bir hata alıyorum.nasıl jenerik karşılaştırıcısı (IComparer) Tümceyi idare yapabilir?

public int Compare(T x, T y) 
{ 
    PropertyInfo propertyInfo = typeof(T).GetProperty(sortExpression); 
    IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null); 
    IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null); 

    if (obj1 == null) obj1 = String.Empty; // This doesn't work! 
    if (obj2 == null) obj2 = String.Empty; // This doesn't work! 

    if (SortDirection == SortDirection.Ascending) 
     return obj1.CompareTo(obj2); 
    else 
     return obj2.CompareTo(obj1); 
} 

Şimdilik buna sıkıca takıldım! Herhangi bir yardım takdir edilecektir. T bir genel tür olduğundan

cevap

15

. Eğer yapmak boş değerlere karşılaştırmak için bir planı var olması gerektiği olduğunu Ne. Böyle

I (ikincisi) yapmaya çalışıyordu ama sadece çalışmak için bir şey elde edemezsiniz ne
if (obj1 == null && obj2 == null) 
    return 0; 
else if (obj1 == null) 
    return -1; 
else if (obj2 == null) 
    return 1; 
else 
    return obj1.CompareTo(obj2); 
+0

Teşekkürler Anthony, bu bir tedavi! Aslına bakarsan neden basit bir çözümü göremedim ... – NickG

0

, bunu bir String değer atanamıyor; Sadece T türünde bir değer atayabilirsiniz. Yalnızca dizeleri karşılaştırmak için bu kullanacağız ise String yerine T kullanın. Aksi takdirde, sıfır denetimi ekleyin ve null'un hangi sırada düşmesi gerektiğine karar verin.

+0

olarak. Boş yerine yeni bir boş T nesnesini nasıl beyan edeceğimi bilmiyorum. Hala jeneriklerin dürüst olmak için kafam karıştı! – NickG

+1

@Nick, bir referans türü için varsayılan 'T' için hala boş olacaktır. Bir T 'new()' kısıtlaması bulunduğunda, bir "T" nin sizin yönteminize dahil edilmesine izin verecek, ancak aynı zamanda tüm "T" anlamına gelecektir. Adayların kamu parametresiz bir kurucuya sahip olması gerekecek. Bu özel durumda, kodunuzdaki boş değerlerle etkin bir şekilde başa çıkabilmeniz için bunu bir şart haline getirmemelisiniz. –

0
IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null) ?? ""; 
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null) ?? ""; 

Bu temelde obj1 artık "o boş olursa, obj1" olacaktır (x, null) veya PropertyInfo.GetValue değeri olacağı anlamına gelir.

Ya

sorun GetValue gibi bir şey yapabileceğini boş çöker olduğunu ise: T etkili şekilde bir dize olmak kısıtlıydı sürece sizin T boş bir dize olarak tedavi edemez

IComparable obj1 = ""; 
try { obj1 = (IComparable)propertyInfo.GetValue(x, null); } catch {} 
1
if (SortDirection == SortDirection.Ascending) 
    return Comparer<T>.Default.Compare(obj1, obj2); 
else 
    return Comparer<T>.Default.Compare(obj2, obj1);