Как лучше проверить, является ли данный объект определенным типом значения?
Ниже приведены 2 наиболее часто используемых подхода для проверки перед распаковкой.
myObject.GetType() == typeof(MyValueType)
IL_0001: callvirt System.Object.GetType
IL_0006: ldtoken UserQuery.MyValueType
IL_000B: call System.Type.GetTypeFromHandle
IL_0010: call System.Type.op_Equality
myObject is MyValueType
IL_0001: isinst UserQuery.MyValueType
Кроме того, мне интересно, почему C# звонит System.Type.op_Equality
вместо ceq
Разве это не проверка на равенство ссылок?
Обновить
На самом деле, есть 3-й способ. (из C# 5.0 в двух словах)
MyValueType? x = myObject as MyValueType?;
Тогда проверь x.HasValue
и использовать x.Value
Какой из 3 вы бы использовали?
2 ответа
Мне интересно, почему C# звонит
System.Type.op_Equality
вместоceq
,
Потому что типы сравниваются по значению, а не по ссылке. В памяти может быть два типа объектов, которые относятся к одному типу.
Какой из трех вы бы использовали?
Если вы хотите узнать, принадлежит ли экземпляр определенному типу, есть оператор, специально предназначенный для решения этой проблемы и одной этой проблемы: is
, Почему бы вам никогда не использовать инструмент, специально разработанный для решения вашей проблемы? Если вы заменяете крышу, и у вас есть выбор между кровельным топориком и молотком, я надеюсь, что вы бы использовали кровельный топорик.
Теперь, если вам нужно выполнить проверку типа и получить значение, то я был бы склонен использовать as
потому что это оператор, специально разработанный для решения этой проблемы.
Если перегружен ==
оператор существует, он является предпочтительным. Если нет, то какой в этом смысл?
Помимо выполнения измерения для определения того, что быстрее, я думаю, что проверка на равенство типов будет быстрее, потому что JIT содержит специальную оптимизацию, которая распознает этот шаблон и оптимизирует его в полной мере. С другой стороны, может быть, isinst
будет скомпилирован с теми же инструкциями, если JIT распознает, что вы приводите к типу значения (который не может иметь подтипы).
Ваш третий метод проверки не может превзойти второй, потому что вы требуете, чтобы JIT делал больше, чем раньше. В лучшем случае это оптимизировалось обратно во 2-й класс, но я был бы удивлен, увидев это, учитывая слабые возможности оптимизации текущего JIT.