1

When I run the following type check code, it produces the result:

True
False

Why is this?

Module VBModule

    Class TypeKey(Of T)
        Public Sub New()

        End Sub
        Public Shared Operator =(k0 As TypeKey(Of T), k1 As TypeKey(Of T)) As Boolean
            Return True
        End Operator
        Public Shared Operator <>(k0 As TypeKey(Of T), k1 As TypeKey(Of T)) As Boolean
            Return False
        End Operator
        Public Shared Operator =(k0 As TypeKey(Of T), k1 As Object) As Boolean
            Return False
        End Operator
        Public Shared Operator <>(k0 As TypeKey(Of T), k1 As Object) As Boolean
            Return True
        End Operator
    End Class
    
    Public Function is_same_type(Of U, V)() As Boolean
        Return New TypeKey(Of U)() = New TypeKey(Of V)()
    End Function
 
    Sub Main()
        Console.WriteLine(New TypeKey(Of Integer)() = New TypeKey(Of Integer)())
        Console.WriteLine(is_same_type(Of Integer, Integer)())
    End Sub
  
End Module

When testing on an online VBNET IDE, there are no warnings.

  • 1
    Because `is_same_type(Of U, V)` is [compiled once](https://stackoverflow.com/questions/68136879/new-modifier-works-unexpectedly-inside-a-generic-method-call#comment120427309_68136879), not per each `U, V`. Hence it's compiled based on what is known about `U, V` at the time of compilation, which is that they are `object`. – GSerg Aug 01 '21 at 16:21
  • Does this answer your question? [`new` modifier works unexpectedly inside a generic method call \[duplicate\]](https://stackoverflow.com/q/68136879/11683) – GSerg Aug 01 '21 at 16:24
  • Perhaps you're used to C++ templates and are expecting generics to behave the same way? If you want to check for type equality, there are ways of doing it using `Type`. If you want `is_same_type` to work, then you can't use an `Operator` because they can't be generic (except in terms of the containing class) so you can't get one that works for two potentially different type parameters on `TypeKey`; you'll need to write a non-operator function instead. – Craig Aug 02 '21 at 13:41

1 Answers1

0

there are no warnings

That's because you have another overload with an Object parameter. So, it falls back to that.

Well, why does it fall back to the overload with the Object parameter, to begin with?

That's because Overload Resolution is handled at compile-time, not run-time. During compile-time, the compiler knows nothing about your type V. It has no way of knowing that it's actually the same type as U in this particular instance. So, it always uses the overload with Object.

You can actually confirm this in two ways:

  1. If you hover over the = operator, you can see that the overload that's being used is =(k0 As TypeKey(Of U), k1 As Object):

    enter image description here

  2. If you remove (or comment out) that overload, you get a compiler error with the following message:

    Overload resolution failed because no accessible '=' can be called with these arguments:

    'Public Shared Operator =(k0 As VBModule.TypeKey(Of U), k1 As VBModule.TypeKey(Of U)) As Boolean': Value of type 'VBModule.TypeKey(Of V)' cannot be converted to 'VBModule.TypeKey(Of U)'.

    Try it online.

  • That is a very nice answer but i dont see a solution in it, if there is no solution could you please state as such. –  Aug 01 '21 at 17:24
  • @Vye A solution to what exactly? You didn't specify the actual requirements of what you're trying to do. Your question was simply "why does my code behave like this?". To provide a solution, we need to know what your end goal is. Are you just trying to make `Dim isEqual = New TypeKey(Of SomeType1)() = New TypeKey(Of SomeType2)()` more concise? Do you actually want the `=` operator to _always_ return true for any two `TypeKey` objects regardless of the generic type arguments or was the `Return True` just a placeholder? – 41686d6564 stands w. Palestine Aug 01 '21 at 18:01
  • It might be better to post this as a new question. I can't say for sure until you describe the requirements. I might edit the answer to address them if the original question isn't changed drastically. – 41686d6564 stands w. Palestine Aug 01 '21 at 18:02
  • @4168d6564 I am looking for a solution that allows generic functions to use overloaded operators correctly; and as for what I am trying to use it for `is_same_type(Of U, V)()` should explain that in its name. –  Aug 02 '21 at 11:06
  • @Vye They _are_ using overloaded operators/methods correctly. They might not be doing what you had expected but they're doing what they're supposed to do as explained above. Are you sure this isn't an [XY problem](https://xyproblem.info/)? With the current information you provided, I don't think I (or anyone) can suggest a solution. I asked you several questions in my previous comment but you seem to have ignored most of them. Based on how you answer them, I might be able to propose a solution for the _actual_ problem that you're trying to solve. – 41686d6564 stands w. Palestine Aug 02 '21 at 13:32