VB.Net - come supportare la conversione di tipo implicita e l'uguaglianza personalizzata
-
02-07-2019 - |
Domanda
Risolto: vedi le note in fondo
Sto implementando una classe generica che supporta due funzionalità, la conversione di tipo implicita e gli operatori di uguaglianza personalizzati. Bene, supporta anche l'uguaglianza IN, se lo fa.
1) if ( "value" = myInstance ) then ...
2) Dim s As String = myInstance
3) Dim s As String = CType(myInstance,String)
Il problema che sto riscontrando è che se supporto la conversione implicita n. 2, non riesco a far funzionare i miei operatori di uguaglianza, poiché si lamentano del fatto che nessuna conversione è la più specifica.
L'errore che ottengo è questo (semplificato un po 'per brevità):
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.
Qual è il modo migliore per implementarlo. Altrettanto importante, cosa dovrei lasciare fuori? Ho implementato le seguenti conversioni
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
Nel mio operatore di ampliamento faccio alcune riflessioni, motivo per cui volevo essere in grado di eseguire una conversione implicita DOWN in String quando faccio un confronto o un'assegnazione con la stringa sul lato sinistro.
A) SomeObject.StringPropertySetter = MyClass
Correzione (modifica)
Ho esagerato con ciò che ho implementato, perché non capivo cosa stesse succedendo. Il confronto tra i tipi di base (ovvero stringa / doppio / guida) avviene tramite il tipo di ampliamento (...) come operatore String (o Guid, ecc.). Alla fine, ho appena implementato queste funzioni e tutti i miei casi di test continuano a passare, oltre all'assegnazione dalla classe a un'istanza di 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)
i commenti sono in stile c, ma il codice è vb.net
Naturalmente la lezione è un po 'più complicata di così, ma questo mi dà tutto ciò di cui avevo bisogno :)
Soluzione
Non dovresti sovrascrivere l'operatore =. Se hai conversioni implicite in tipi come string
o int
, lascia che l'operatore di uguaglianza predefinito subentri.
Come regola generale, se è necessario personalizzare l'uguaglianza per una classe, è necessario sostituire il metodo Equals (oggetto)
.