Почему для определения эквивалентных типов необходимо использовать 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'."





Это меня удивляет, учитывая способ загрузки типов. Откуда вы это слышали?
документы для System.Type.Equals (Type) предполагает, что он сравнивается с помощью свойства UnderlyingSystemType, но я не уверен, при каких обстоятельствах два разных объекта Type будут иметь один и тот же базовый тип системы.
Мне было бы действительно интересно увидеть пример, в котором это имело значение ... мой угадать заключается в том, что из любого места в "пользовательском коде" они будут одинаковыми, но там, где это имеет значение, может быть какой-то хитрый код BCL.
PS. Рассматривая реализацию Type.Equals (), он действительно сравнивает свойства UnderlyingSystemType на предмет ссылочного равенства.
@CristiDiaconescu: Возможно, здесь можно было добиться повышения эффективности очень легкий?
Может быть. Подсказки Re # обычно имеют более очевидные преимущества с точки зрения функциональности или удобочитаемости ...
Глядя на исходный код в Reflector, я не вижу, как Type.Equals (t1, t2) будет обрабатываться иначе, чем t1 = t2. (На самом деле нет Type.Equals; он фактически вызовет Object.Equals).
В C# T1 == T2 работает нормально.
Нет, Type действительно переопределяет Equals, насколько я понимаю ... по крайней мере, в .NET 3.5.
Он переопределяет Type.Equals (Type), но не Equals (Type, Type), которому будет сопоставляться oper ==, следовательно, соответствующий здесь.
Согласно это, оператор равенства VB выполняет сравнение значений, а не сравнение ссылок. Использование Type.Equals (t1, t2) заставляет его выполнять сравнение ссылок. Если бы t1 и t2 были типами, я бы подумал, что любой из них будет работать, но я парень C#, так что я знаю. Я бы, вероятно, предпочел использовать синтаксис is для известных классов и IsInstanceOf, если меня не волнует точное соответствие типа.
Typeof a Is Boolean
a.GetType().IsAssignableFrom( b.GetType() )
Большое спасибо за ссылку, теперь я понял. Вместо этого мне нужно использовать оператор Is, например t1 - это t2.
IsInstanceOf не является методом GetType. Однако есть IsInstanceOfType, но он принимает в качестве аргумента объект (а не тип) и предназначен для использования следующим образом: typeof (int) .IsInstanceOfType (3). Я думаю, что вам нужно IsAssignableFrom, который предназначен для использования следующим образом: typeof (Animal) .IsAssignaleFrom (typeof (Leon)
Вы, наверное, правы - я думаю, что изначально я думал о точном равенстве типов (и просто добавил дополнительный GetType ()). Однако AssignableFrom лучше работает с неточным соответствием.
В 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 комментарии Пола Викса о том, почему некоторые отдельные идиомы BASIC были перенесены, а другие - нет. Я считаю, что в этом случае нужно было избежать путаницы, поскольку VB.NET представил
ObjectA = ObjectC ', что заставляет ObjectA ссылаться на те же объекты, на которые ссылается ObjectC.
В то время как в VB6 было установлено ObjectA = ObjectC
По той же причине, по которой, когда объекты были введены в VB4, IS и Set использовались для работы с объектом вместо перегрузки equals.
В конечном итоге эти причуды стали частью Основного способа кодирования.
В Resharper 7 есть конкретное предложение для сравнения экземпляров Type - он предлагает изменить t1.Equals (t2) на t1 == t2 (где t1 и t2 относятся к типу
Type). Это предложение не отображается, скажем, для экземпляров типаstringилиobject. (Я пробовал C#, но, думаю, это то же самое для VB). Есть идеи, почему?