Ответ 1
Он использует инструкцию IL isinst
для выполнения броска вместо castclass
, которая используется при кастинге. Это специальная инструкция, которая выполняет листинг, если она действительна, иначе оставляет null
в стеке, если это не так. Нет, это не просто подавляет исключение, а на порядок быстрее, чем это делает.
Обратите внимание, что существуют некоторые различия в поведении между инструкцией isinst
и castclass
- основная из них заключается в том, что isinst
не учитывает пользовательские операторы приведения, она рассматривает только иерархию прямого наследования, например. если вы определяете следующие два класса без иерархии наследования, но явный оператор литья:
class A
{
public int Foo;
}
class B
{
public int Foo;
public static explicit operator B(A a)
{
return new B { Foo = a.Foo };
}
}
Тогда будет выполнено следующее:
var a = new A { Foo = 3 };
var b = (B)a;
Console.WriteLine(b.Foo); // prints 3
Однако следующее не компилируется с ошибкой "Невозможно преобразовать тип" A "в" B "посредством преобразования ссылок, преобразования бокса, преобразования для распаковки, преобразования конверсий или преобразования нулевого типа"
var a = new A { Foo = 3 };
var b = a as B;
Итак, если у вас есть настроенные пользователем настройки (которые обычно являются плохими идеями по ссылочным типам, по этой причине и другим), тогда вы должны знать об этой разнице.