Как лучше проверить, является ли данный объект определенным типом значения?

Ниже приведены 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.

Другие вопросы по тегам