VB.Net: cómo admitir la conversión de tipo implícita y la igualdad personalizada
-
02-07-2019 - |
Pregunta
Corregido: vea las notas en la parte inferior
Estoy implementando una clase genérica que admite dos características, conversión de tipo implícita y operadores de igualdad personalizados. Bueno, también es compatible con la igualdad IN, si lo hace.
1) if ( "value" = myInstance ) then ...
2) Dim s As String = myInstance
3) Dim s As String = CType(myInstance,String)
El problema que tengo es que si apoyo # 2, conversión implícita, entonces no puedo hacer que mis operadores de igualdad funcionen, ya que se quejan de que ninguna conversión es la más específica.
El error que obtengo es este (simplificado un poco por brevedad):
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.
¿Cuál es la mejor manera de implementar esto? Igual de importante, ¿qué debo dejar de lado? He implementado las siguientes conversiones
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
En mi operador de ampliación hago un poco de reflexión, por eso quería hacer una conversión implícita DOWN a String cuando hago una comparación o asignación con la cadena en el lado izquierdo.
A) SomeObject.StringPropertySetter = MyClass
Reparar (editar)
Fui por la borda en lo que implementé, porque no entendía lo que estaba sucediendo. La comparación entre los tipos base (es decir, cadena / doble / guid) se realiza a través del tipo de ampliación ctype (...) como operador de cadena (o guid, etc.). Al final, acabo de implementar estas funciones y todos mis casos de prueba aún pasan, además de la asignación de la clase a una instancia de tipo 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)
Los comentarios son estilo c, pero el código es vb.net
Por supuesto, la clase es un poco más complicada que eso, pero eso me da todo lo que necesitaba :)
Solución
No debe anular el operador =. Si tiene conversiones implícitas a tipos como string
o int
, deje que el operador de igualdad predeterminado se haga cargo.
Como regla general, si necesita personalizar la igualdad para una clase, debe anular el método Equals (object)
.