Fixed: See notes at bottom
I am implementing a generic class that supports two features, implicit type conversion and custom equality operators. Well, it supports IN-equality as well, if it does that.
1) if ( 'value' = myInstance ) then ... 2) Dim s As String = myInstance 3) Dim s As String = CType(myInstance,String)
The problem I am having is that if I support #2, implicit conversion, then I can’t get my equality operators to work, since they complain about no conversion being the most specific.
The error I get is this (simplified a bit for brevity):
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.
What is the best way of implementing this. Just as importantly, what should I leave out? I have implemented the following conversions
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
In my widening operator I do some reflection, which is why I wanted to be able to do an implicit convert DOWN to String when I do a comparison or assignment with the string on the left side.
A) SomeObject.StringPropertySetter = MyClass
Fix (edit)
I went way overboard in what I implemented, because I didn’t understand what was happening. Comparison between the base types (ie string/double/guid) takes place via the widening ctype(…) as String (or Guid,etc) operator. In the end, i just implemented these functions and all my test cases still pass, in addition to assignment from the class to a base type instance
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)
comments are c style, but code is vb.net
Of course the class is a little more complicated than that, but that give me everything I needed 🙂
You should not override the = operator. If you have implicit conversions to types such as
stringorint, then let the default equality operator take over.As a general rule, if you need to customize equality for a class you should override the
Equals(object)method.