Почему Type.Equals (t1, t2), а не оператор равенства? - PullRequest
3 голосов
/ 14 ноября 2008

Почему для определения эквивалентных типов должен использоваться Type.Equals(t1, t2), а не оператор равенства (например, для VB.NET, t1 = t2)?

Это кажется несовместимым с другими частями .NET API.

Пример в VB.NET:

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

вызывает ошибку во время компиляции "Operator '=' is not defined for types 'System.Type' and 'System.Type'."

Ответы [ 4 ]

4 голосов
/ 14 ноября 2008

Согласно this , оператор равенства VB выполняет сравнение значений, а не эталонное сравнение. Использование Type.Equals (t1, t2) заставляет его делать сравнение ссылок. Если бы t1 и t2 были типами, я бы подумал, что любой из них будет работать, но я парень на C #, так что я знаю. Вероятно, я бы предпочел использовать синтаксис is для известных классов и IsInstanceOf, если меня не интересует точное соответствие типов.

Typeof a Is Boolean

a.GetType().IsAssignableFrom( b.GetType() )
2 голосов
/ 14 ноября 2008

Учитывая способ загрузки типов, меня это удивляет. Откуда ты это услышал?

Документы для System.Type.Equals (Type) предполагают, что он сравнивается с помощью свойства UnderlyingSystemType , но я не уверен, при каких обстоятельствах два разных объекта Type будут иметь тот же базовый тип системы.

Мне было бы очень интересно увидеть пример, где это имеет значение ... мое предположение заключается в том, что из любого места в "коде пользователя" они будут одинаковыми, но может быть какая-то хитрость Код BCL, где это имеет значение.

0 голосов
/ 14 ноября 2008

В VB.NET Is - это оператор языка, используемый для проверки на равенство типов. Обратите внимание, что Type.Equals проверяет, указывают ли две переменные одного типа на один и тот же объект. Как показано на примере ниже.

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

Это было сделано потому, что история оператора «равно» на языке BASIC. Когда в VB4 были представлены объекты, IS был выбран для проверки на равенство, так как считалось, что перегрузка equals будет проблематичной.

Я предлагаю поискать в google и usenet комментарии Пола Викса о том, почему некоторые отдельные базовые идиомы были перенесены, а другие - нет. Я считаю, что в этом случае нужно было избегать путаницы, поскольку VB.NET представил

ObjectA = ObjectC ', который заставляет ObjectA ссылаться на те же объекты, на которые ссылается ObjectC.

В то время как в VB6 было установлено ObjectA = ObjectC

По той же причине, по которой объекты были введены в VB4 IS и Set, использовались для работы с объектами вместо перегрузки равных.

В конечном итоге эти причуды стали частью Базового Пути кодирования.

0 голосов
/ 14 ноября 2008

Глядя на исходный код в Reflector, я не вижу, как Type.Equals (t1, t2) будет обрабатываться иначе, чем t1 = t2. (На самом деле Type.Equals не существует; фактически он будет вызывать Object.Equals).

В C # T1 == T2 работает просто отлично.

...