views:

1321

answers:

4

Why must Type.Equals(t1, t2) be used to determine equivalent types, and not the equality operator (e.g. for VB.NET, t1 = t2)?

It seems inconsistent with other parts of the .NET API.

Example in VB.NET:

If GetType(String) = GetType(String) Then Debug.Print("The same, of course") End If

causes a compile-time error of "Operator '=' is not defined for types 'System.Type' and 'System.Type'."

+1  A: 

Given the way types are loaded, that surprises me. Where did you hear this from?

The docs for System.Type.Equals(Type) suggest that it's comparing via the UnderlyingSystemType property, but I'm not sure under what circumstances two different Type objects would have the same underlying system type.

I'd be really interested to see an example where this mattered... my guess is that from anywhere in "user code" they'll be the same thing, but there may be some cunning BCL code where it matters.

Jon Skeet
A: 

Looking at the source code in Reflector, I can't see how Type.Equals(t1,t2) would be handled any differently than t1 = t2. (There is actually no Type.Equals; it will actually call Object.Equals).

In C#, T1 == T2 works just fine.

James Curran
No, Type does override Equals, as far as I can see... at least in .NET 3.5.
Jon Skeet
It overrides Type.Equals(Type), but not Equals(Type, Type) which is the one the oper== would be mapped to, hence the relevant one here.
James Curran
+3  A: 

According to this, the VB equality operator does a value comparison, not a reference comparison. Using Type.Equals(t1,t2) forces it to do reference comparison. If t1 and t2 are types, I would think that either would work, but I'm a C# guy so what do I know. I'd probably prefer using the is syntax for known classes and IsInstanceOf, if I don't care about exact type match.

Typeof a Is Boolean

a.GetType().IsAssignableFrom( b.GetType() )
tvanfosson
Many thanks for the link, I understand it now. I have to use the Is operator instead, e.g. t1 Is t2.
IsInstanceOf is not a method from GetType. There's however IsInstanceOfType but takes an object (not a type) as the argument and is meant to be used like this: typeof(int).IsInstanceOfType(3). I thing what you want is IsAssignableFrom that is meant to be used like this: typeof(Animal).IsAssignaleFrom(typeof(Leon)
Olmo
You're probably right -- I think I was originally thinking exact type equality (and simply put in an extra GetType()). AssignableFrom works better for non-exact matching, though.
tvanfosson
A: 

In VB.NET The Is is the language operator used to test type equality. Note that Type.Equals test whether two variable of the same type are pointed to the same object. As shown by the below example.

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim X As New TestObject
        Dim Y As New TestObject

        If X Is Y Then MsgBox("The Same 1")
        If Type.Equals(X, Y) Then MsgBox("The Same 2")

        X = Y
        If X Is Y Then MsgBox("The Same 3")

        If Type.Equals(X, Y) Then MsgBox("The Same 4")
    End Sub
End Class

Public Class TestObject
    Public Value As Double
End Class

This was done because the history of the 'equals' operator in the BASIC language. When Objects were introduced in VB4 IS was chosen to test for equality as it was felt that overloading equals would be problematic.

I suggest searching google and usenet for Paul Vicks comments on why some individual BASIC idioms were ported and why other were not. I believe in this case was to avoid confusion as VB.NET introduced

ObjectA = ObjectC 'which causes ObjectA to reference the same objects as referenced by ObjectC.

While in VB6 it was Set ObjectA = ObjectC

The same reason why when objects were introduced in VB4 IS and Set were used to deal with object instead of overloading equals.

Ultimately these quirks became part of the the Basic Way of coding.

RS Conley