2009-07-15 2 views
25

Сегодня коллега задал мне интересный вопрос - является ли ключевое слово/оператор C# «считаться отражением?C# «есть» оператор - это отражение?

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

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

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

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

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

+0

http://stackoverflow.com/questions/57701/what-are-the-performance-characteristics-of-is-reflection-in-c?lq=1 – nawfal

ответ

31

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

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

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

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

+0

Я ничего не редактировал, но, возможно, я должен уточнить, что я имею в виду под «дорогим». Я мало знаю об эффективности IL, но у FxCop есть предупреждение, если вы создаете код, который испускает команду isinst и castclass, поскольку они считают ее неэффективной или «дорогой». –

+2

Как я упоминал во втором правиле, вы должны использовать 'as', за которым следует 'null' для ссылочных типов. Вместо этого вы используете 'is', за которым следует бросок, на что FxCop предупреждает вас. –

+2

Для того, что стоит, на Compact Framework, IL, который должен явно проверять RTTI (например, 'isinst' и' castclass'), идет так же медленно, как отражение, в то время как callvirt сильно оптимизирован. Мораль: старайтесь избегать использования конструкций типа, где могут работать виртуальные/абстрактные методы. –

5

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

EDIT:

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

+0

Оператор 'is' возвращает true/false, а не ноль. – SolutionYogi

+1

Я думаю, вы думаете об операторе «как» – Matt

+0

То, что вы описали, является оператором «как». Оператор «is» - это, по сути, одна и та же операция, только с другим возвращаемым значением. – Charlie

1

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

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

+0

Было бы еще «правильным» сказать, что отражение анализирует элементы класса, а не объекты, так как вам не нужно иметь экземпляр живого. Также отражение позволяет «обнаруживать», какие классы у вас есть на собрании, а не только члены и другая информация о классе. –

+0

@ Danny Varod - Не все языки имеют классы или сборки. –

+0

C++ имеет классы и библиотеки, Java имеет классы и пакеты. Объектно-ориентированное программирование определяет разницу между объектом и классом. –

Смежные вопросы