2013-10-06 2 views
2

Disons que je la classe suivante:Comment mettre en œuvre multi type IComparable/IEquatable en C#

public sealed class ScaleValue : 
    IComparable, IComparable<ScaleValue>, IEquatable<ScaleValue> 
{ 
    public double Value 
    { get; set;} 
    public string Definition 
    { get; set;} 

    // interface methods 
    ... 
} 

Si je veux faire ma classe comparable à un double dois-je inclure simplement IComparable<double> et mettre en œuvre cette façon ou dois-je le faire d'une autre manière?

Et quand je veux que ma classe soit comparable aux doubles devrait le double.CompareTo donner le même résultat que le ScaleValue.CompareTo?

et que diriez-vous de Equals? Je pense que j'ai mis les responsabilités mal dans ma conception. Je pense que ma meilleure option est de faire une classe Scale avec une méthode ContainsValue(double Value). De cette façon, je peux rechercher la valeur et garder les responsabilités là où elles sont nécessaires.

+0

Le problème ici est qu'un contrôle comparable ne sera plus symétrique. someScaleValue.CompareTo (1.2) retournera une valeur, mais '1.2.CompareTo (someScaleValue)' lèvera une exception, car la version '' double'' de la comparabilité ne saura pas comment gérer votre type. C'est un problème. – Servy

+1

Vous avez déjà un double ici, comparez simplement cela (rappelez-vous le principe KISS) – Alex

+0

Pourquoi voudriez-vous que votre classe soit comparable aux doubles? Essayez-vous de faire une méthode statique? Vous avez déjà implémenté IComparable . Dans la méthode Comparer, vous pouvez comparer le membre ScaleValue.Value .. –

Répondre

0

Ce à quoi votre classe est comparable dépend de vous. Vous pouvez le rendre comparable à quoi que ce soit, car la version non générique du IComparable interface prend un object; dans la mise en œuvre de CompareTo method, vous pouvez essentiellement renifler le type de l'objet (à moins qu'il ne soit null). Lorsque vous utilisez la version générique IComparable<T>, vous indiquez que vous implémentez une méthode de comparaison fortement typée à quel que soit le paramètre de type T.

En général, si vous avez une IComparable<T> mise en œuvre pour un type, vous probablement devriez avoir une mise en œuvre IEquatable<T> ainsi. Une implémentation de IComparable/IComparable<T> signifie que ce qui est représenté par la structure a un ordre naturel. La commande implique également qu'il peut y avoir une égalité entre deux instances: si l'instance a de T n'est pas supérieure ou inférieure à l'instance b de T alors doit être égal à. Pour cela, si vous implémentez IComparable/IComparable<T>, alors la logique impose d'implémenter IEquatable/IEquatable<T>. Bien sûr, lorsque vous implémentez IEquatable/IEquatable<T>, vous devez remplacer Equals et GetHashCode.

ce qui signifie que vous devez remplacer tous les opérateurs de comparaison:

  • == (ce qui implique !=)
  • < et <=
  • > et >=
+0

ce que vous m'avez dit, j'ai déjà compris. ce que je veux dire c'est que j'ai un ensemble de ScaleValue nommé Scale'. maintenant je veux vérifier si une certaine valeur 'a' du type' double' est dans la liste. 'Scale.contains (a)'. C'est pourquoi j'ai demandé si je devrais implémenter 'Icomparable '. dans la classe ScaleValue, la définition de propertie est moins importante. – user2038134

+0

@ user2038134 Cela n'a aucun sens. Que faire si vous avez deux propriétés qui exposent 'double'? Une implémentation de 'IComparable ' ne vous donnerait pas ce que vous cherchez. Vous devez utiliser quelque chose comme la méthode d'extension 'Where' dans LINQ pour faire ce que vous voulez. – casperOne

0

Vous ne pouvez pas comparer objets dans une collection à un objet de type différent utilisant contient metho d sauf si vous implémentez un nouveau type de collection pour votre classe ou en utilisant une sorte de méthode d'extension !!!

Questions connexes