VB.Net - Comment prendre en charge la conversion de type implicite ainsi que l’égalité personnalisée
-
02-07-2019 - |
Question
Corrigé: voir les notes en bas
J'implémente une classe générique qui prend en charge deux fonctionnalités, la conversion de type implicite et les opérateurs d'égalité personnalisés. Eh bien, il prend également en charge l’égalité IN, s’il le fait.
1) if ( "value" = myInstance ) then ...
2) Dim s As String = myInstance
3) Dim s As String = CType(myInstance,String)
Le problème que je rencontre est que si je soutiens la conversion implicite n ° 2, je ne parviens pas à faire fonctionner mes opérateurs d'égalité, car ils se plaignent de l'absence de conversion comme étant la plus spécifique.
L’erreur que j’obtiens est la suivante (simplifié un peu par souci de concision):
Overload resolution failed because no accessible '=' is most specific for these arguments:
'Public Shared Operator =(obj As MyClass, data As String) As Boolean': Not most specific.
'Public Shared Operator =(data As String, obj As MyClass) As Boolean': Not most specific.
'Public Shared Operator =(obj1 As MyClass, obj2 As MyClass) As Boolean': Not most specific.
Quel est le meilleur moyen de mettre cela en œuvre? De manière tout aussi importante, que dois-je laisser de côté? J'ai implémenté les conversions suivantes
Operator =(ByVal data As String, ByVal obj As classType) As Boolean (and <>)
Operator =(ByVal obj As classType, byval data As String) As Boolean (and <>)
Operator =(ByVal obj1 As classType, ByVal obj2 As classType) As Boolean (and <>)
Equals(obj as Object) as Boolean
Equals(compareTo as classType ) as Boolean
Equals(compareTo as String) as Boolean
Widening Operator CType(ByVal source As String) As classType
Widening Operator CType(ByVal source As classType) as String
Narrowing Operator CType(ByVal inst As classType) As dataType
Dans mon opérateur d'élargissement, je réfléchis un peu, c'est pourquoi je souhaitais pouvoir convertir implicitement DOWN en chaîne lorsque je fais une comparaison ou une affectation avec la chaîne du côté gauche.
A) SomeObject.StringPropertySetter = MyClass
Correction (modifier) ??
Je suis allé trop loin dans ce que j'ai mis en œuvre, parce que je ne comprenais pas ce qui se passait. La comparaison entre les types de base (c.-à-d. Chaîne / double / guid) s'effectue par l'intermédiaire de l'opérateur d'élargissement (...) en tant qu'opérateur de chaîne (ou de guidage, etc.). En fin de compte, je viens d’implémenter ces fonctions et tous mes cas de test sont toujours satisfaisants, en plus de l’affectation de la classe à une instance de type de base
Public Class MyClass(Of BaseType)
Widening Operator CType(ByVal source As dataType) As MyClass
Widening Operator CType(ByVal source As MyClass) As dataType //conv between inst & base
Equals() // for datatype, classType, object
Operator <>(MyClass,MyClass) // for comparison between two instances
Opeator =(MyClass,MyClass)
les commentaires sont du style c, mais le code est vb.net
Bien sûr, le cours est un peu plus compliqué que cela, mais cela me donne tout ce dont j'avais besoin:)
La solution
Vous ne devez pas remplacer l'opérateur =. Si vous avez des conversions implicites vers des types tels que chaîne
ou int
, laissez l'opérateur de l'égalité par défaut prendre le relais.
En règle générale, si vous devez personnaliser l'égalité pour une classe, vous devez remplacer la méthode Equals (object)
.