Подтвердить что ты не робот

Является ли тип ввода типа IS-оператора или нет?

Я не могу найти ответ на следующий вопрос:

object o = 10; // Box
int i = (int)o; // Unbox

ясно, но следующее не ясно.

bool isInt = o is int; // Is the unbox here or not?
4b9b3361

Ответ 1

Нет, это не unboxing - это просто проверка правильности типа. Не забывайте, что на самом деле есть объект, с типом. Проверка этого типа в основном та же самая операция, независимо от того, является ли значение значением типа бокс-значения или нет. (Возможны некоторые оптимизации для типов значений или любых закрытых типов, так как нет наследования для рассмотрения, но в основном он все еще проверяет "тип" части заголовка объекта.)

Один из способов проверить, что является компиляция кода и просмотр IL с использованием ILASM:

// object o = 10
IL_0000:  ldc.i4.s   10
IL_0002:  box        [mscorlib]System.Int32
IL_0007:  stloc.0

// int i = (int) o;
IL_0008:  ldloc.0
IL_0009:  unbox.any  [mscorlib]System.Int32
IL_000e:  stloc.1

 // bool isInt = o is int
IL_000f:  ldloc.0
IL_0010:  isinst     [mscorlib]System.Int32

Таким образом, он использует isinst - не требуется распаковка.

Ответ 2

Не только он не требует unboxing, логически, он не может.

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

Поэтому для распаковки требуется проверка того, является ли объект этого конкретного типа.

Поэтому, если вы проверяете тип, требуемый для распаковки, то, поскольку для распаковки требуется тестирование типа, мы не сможем распаковываться, пока мы не будем сначала распаковываться...

Поэтому для тестирования типа не требуется распаковка.

Ответ 3

Начиная с С# 7, ключевое слово is приобрело новый прецедент, в соответствии с шаблоном типа. В этом случае происходит разблокировка, например:

object o = 10;
if (o is int i) {
   // i is the unboxed value.
}

Очевидно, это другой случай для исходного сообщения, в котором значение чисто проверяется, так как при использовании is в качестве шаблона вы фактически присваиваете значение. Следовательно, необходимость распаковать в этом случае.

Чтобы быть ясным - ничего не изменилось в оригинальном случае o is int - там не будет никакого распаковки, как в старых ответах. Ключевое слово is только что приобрело новую роль.