2011-01-31 5 views
8

ソート用の汎用オブジェクト比較関数を記述しようとしていますが、比較対象の値の1つがnullのインスタンスが処理されないことに気付きました。オブジェクトがnullの場合、空の文字列と同じ扱いをしたい。私はnull値をString.Emptyに設定しようとしましたが、次にCompareTo()を呼び出すときにObjectがString型である必要があります。汎用比較元(IComparer)がNULLを処理するにはどうすればよいですか?

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); 
} 

私はこれで今非常に固執しています!どんな助けもありがとう。

答えて

15

にはにはnullを比較する計画があります。このような私が(後者)やろうとしましたが、私はちょうど仕事に何かを得ることができないものです

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

ありがとうアンソニー、それは治療を働く!なぜ私は単純な解決策を見つけられないのか分かりません... – NickG

0

Tは汎用タイプなので、Stringの値に割り当てることはできません。それにはTタイプの値しか割り当てることができません。これを使用して文字列を比較する場合は、Tの代わりにStringを使用してください。それ以外の場合は、ヌルチェックを追加して、nullをどこに配置するかを決定します。

+0

として。私はnullの代わりに比較するために新しい空の有効なTオブジェクトを宣言する方法を知らない。私はまだジェネリック医薬品によって正直であると混乱しています! – NickG

+1

@Nickの場合、参照型のデフォルトの 'T'は引き続きnullになります。 'T 'があなたのメソッドの中で' T'をインスタンス化することを可能にする 'T:new()'制約を持っていれば、インスタンス化されていて空の 'T'が得られるかもしれませんが、' T '候補者はパブリックなパラメータのないコンストラクタを持つ必要があります。この特定の状況では、コード内でヌルを効果的に処理できる必要があるため、これを要件にするべきではありません。 –

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

これは、基本的にOBJ1が今「とはヌルであることを起こる場合、OBJ1」となり、(X、ヌル)又はpropertyInfo.GetValueの値となることを意味します。

や問題がGetValueメソッドは次のように何かを行うことができ、ヌルにクラッシュするということであるならば:あなたのTが効果的に文字列であることに制約されない限りあなたは空の文字列としてあなたTを扱うことができない

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);