Operator_Compare with objects stored as Variants

I have two dictionaries, and when both dictionaries contain the same keys, I want to see if the values are the same. The problem is that the dictionary values are variants, and the Operator_Compare function won’t get called. I can’t type-cast explicitly because this is a generic comparison function, and it won’t know what types of objects are in the dictionary.

I know that this is the designed behavior for Variants and Operator_Compare but I’m looking for a solution or workaround.

Dim p1, p2 As TRVector2D

p1 = New TRVector2D(1,1)
p2 = New TRVector2D(1,1)

// TRVector2D implements Operator_Compare
 
Dim bP As Boolean = p1 = p2 // Operator_Compare returns True

Dim v1, v2 As Variant

v1 = p1
v2 = p2

Dim bV As Boolean = v1 = v2 // Operator_Compare not called; returns False

Make a Class Interface named Comparable with a method defined like this:

Function IsSameAs(other as variant) as Boolean

Add the interface to any objects that you want to be able to do this with like this:

Function IsSameAs(other as Comparable) as Boolean 
If not (other IsA TRVector2D) then
  Return False
End If
End Function

Then you’d be able to call

Dim v1, v2 As Comparable

v1 = p1
v2 = p2

Dim bV As Boolean = v1.IsSameAs(v2)
1 Like

Unless you want to modify every possible class like Greg suggested (which is a great way to do it, but not truly generic), you’ll have to dive into the Introspection system to get the name of the objects’ classes and compare them.

1 Like

Thank you, Eric. Yes, that is the way. I wasn’t familiar with the new (to me) Introspection features.

Protected Function VariantContentsAreEqual(v1 as Variant, v2 as Variant) As Boolean
  // Use introspection to get the type info of the objects
  Dim typeInfo1 As Introspection.TypeInfo = Introspection.GetType(v1)
  Dim typeInfo2 As Introspection.TypeInfo = Introspection.GetType(v2)
  
  If typeInfo1.IsClass And typeInfo2.IsClass Then
    Dim o1 As Object = v1
    Dim o2 As Object = v2
    
    // Check if both objects are of the same type
    If typeInfo1.FullName = typeInfo2.FullName Then
      // Look for Operator_Compare in the first object
      
      Dim methods() As Introspection.MethodInfo = typeInfo1.GetMethods
      For Each methodInfo As Introspection.MethodInfo In methods
        If methodInfo.Name = "Operator_Compare" Then
          // If Operator_Compare exists, invoke it dynamically
          
          Return methodInfo.Invoke(v1, Array(v2)) = 0
        End If
      Next
    End
  End
  
  Return v1 = v2
  
End Function

These are acceptable hoops to jump through; the function is called infrequently.

And it’s a completely generic solution—this functionality is used in a few projects, and we won’t know about the types of objects it compares to, nor should the project code that indirectly calls this function do anything special.