C # оператор "is" - это отражение? - PullRequest
28 голосов
/ 16 июля 2009

Коллега задал мне сегодня интересный вопрос - считается ли ключевое слово / оператор C # "отражением"?

object tmp = "a string";
if(tmp is String)
{
}

Как этот оператор реализован за кадром? Требуется ли рефлексия или самоанализ? Или из-за строго типизированной природы языка тип объекта сразу доступен как атрибут верхнего уровня объекта в памяти?

MSDN утверждает, что:

Обратите внимание, что оператор is рассматривает только ссылочные преобразования, преобразования в блокировку и преобразования в распаковку. Другие преобразования, такие как пользовательские преобразования, не рассматриваются оператором is.

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

Ответы [ 3 ]

34 голосов
/ 16 июля 2009

При ссылке на ECMA-335 оператор is генерирует инструкцию IL модели объекта isinst (Раздел III §4.6), которая является частью базового набора команд, а не частью Библиотека отражений (Раздел IV §5.5).

Edit: оператор is чрезвычайно эффективен по сравнению с библиотекой отражений. Вы можете выполнить в основном тот же тест намного медленнее с помощью рефлексии:

typeof(T).IsAssignableFrom(obj.GetType())

Редактировать 2: Вы не правы относительно эффективности инструкций castclass и isinst (которые вы сейчас отредактировали из поста). Они высоко оптимизированы в любой практической реализации виртуальной машины. Единственная реальная проблема с производительностью - это возможность для castclass вызвать исключение, которого вы можете избежать, используя оператор C # as и тест для null (для ссылочных типов) или оператора is, за которым следует приведение (для типов значений).

5 голосов
/ 16 июля 2009

Оператор is по существу определяет, возможно ли приведение, но вместо того, чтобы генерировать исключение, когда приведение невозможно, возвращается false. Если вы подумаете о том, чтобы применить отражение, то это тоже отражение.

EDIT:

После некоторых исследований я обнаружил, что приведение выполняется в IL по инструкции castclass, в то время как оператор is отображается на инструкцию isinst. FxCop имеет правило , которое предупреждает вас, если вы делаете ненужные приведения, сначала используя isinst, а затем инструкцию castclass. Несмотря на то, что операции эффективны, они все равно имеют затраты на производительность.

1 голос
/ 16 июля 2009

В других языках есть информация времени выполнения, достаточная для поддержки динамического приведения, и в то же время ничего такого, что можно было бы описать как отражение (очевидный пример - C ++).

Таким образом, отражение относится к дополнительным возможностям, помимо простого обнаружения типа объекта. «Отражение» на объекте подразумевает, например, умение ходить по его элементам.

...