11
votes

Comment puis-je faire mon comparateur générique (Icomarer) Manipulez-vous des NULLS?

J'essaie d'écrire un comparateur d'objet générique pour le tri, mais je l'ai remarqué ne gère pas l'instance dans laquelle l'une des valeurs qu'il comparait est null. Lorsqu'un objet est NULL, je veux que cela traite la même chose que la chaîne vide. J'ai essayé de définir les valeurs nulelles à String.empty, mais j'obtiens alors une erreur d'erreur "L'objet doit être de type chaîne de type" lors de l'appel de la comparète () sur celui-ci.

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


0 commentaires

4 Réponses :


0
votes

Etant donné que t est un type générique, vous ne pouvez pas l'affecter une valeur string ; Vous ne pouvez attribuer qu'une valeur de type t . Si vous n'allez utiliser que pour comparer les chaînes, utilisez chaîne au lieu de t . Sinon, ajoutez la vérification null et décidez où dans l'ordre null devrait tomber.


2 commentaires

C'est ce que j'essayais de faire (ce dernier) mais je ne peux tout simplement pas avoir rien à travailler. Je ne sais pas comment déclarer un nouvel objet T vide valide pour celui-ci de comparer au lieu de la null. Je suis toujours confondu par des génériques pour être honnête!


@Nick, une valeur par défaut t pour un type de référence serait toujours null. Un instancié mais sinon vide t pourrait être obtenu si t avait un où T: nouvelle () contrainte, ce qui vous permettrait d'instancier un < Code> T à l'intérieur de votre méthode, mais cela signifierait également que tous les candidats t devraient avoir un constructeur sans paramètre public. Dans cette situation particulière, vous ne devriez pas en faire une exigence car vous devriez être en mesure de traiter efficacement avec NULLS dans votre code.



0
votes
IComparable obj1 = "";
try { obj1 = (IComparable)propertyInfo.GetValue(x, null); } catch {}

0 commentaires

22
votes

Vous ne pouvez pas traiter votre t comme une chaîne vide, sauf si votre T était effectivement contraint d'être une chaîne. Ce que vous devriez doeur d'avoir un plan de comparaison de NULLS. Tels que xxx


1 commentaires

Merci Anthony, ça marche un régal! Je ne sais pas vraiment pourquoi je ne semble jamais repérer la solution simple ...



4
votes
if (SortDirection == SortDirection.Ascending)
    return Comparer<T>.Default.Compare(obj1, obj2);
else
    return Comparer<T>.Default.Compare(obj2, obj1);

0 commentaires