Каковы характеристики производительности отражения is в C#?[дубликат]
-
09-06-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
- Производительность оператора C# is 8 ответов
Его показано что приведение «as» происходит намного быстрее, чем приведение префикса, но как насчет отражения «is»?Насколько плохо?Как вы можете себе представить, поиск «есть» в Google не очень эффективен.
Решение
Есть несколько вариантов:
- А классический актерский состав:
Foo foo = (Foo)bar
- А
as
оператор кастинга:Foo foo = bar as Foo
- А
is
тест:bool is = bar is Foo
- А классический актерский состав нужно проверить, если
bar
можно безопасно привести кFoo
(быстро), а затем действительно сделайте это (медленнее) или создайте исключение (очень медленно). - А
as
оператор нужно проверить, еслиbar
можно применить, затем выполните приведение, или, если его нельзя безопасно применить, он просто возвращаетсяnull
. - А
is
оператор просто проверяет, еслиbar
можно привести к Foo и вернутьboolean
.
А is
Тест выполняется быстро, поскольку он выполняет только первую часть полной операции литья.А as
Оператор выполняется быстрее, чем классическое приведение, поскольку не генерирует исключение в случае сбоя приведения (что делает его полезным для ситуаций, когда вы вполне обоснованно ожидаете, что приведение может завершиться неудачей).
Если вам просто нужно знать, является ли переменная bar
это Foo
затем используйте is
оператор, НО, если вы собираетесь проверить, если bar
это Foo
, и если так, затем бросьте это, то вам следует использовать as
оператор.
По сути, каждый актерский состав должен выполнять эквивалент is
для начала проверьте внутреннюю проверку, чтобы убедиться, что приведение допустимо.Итак, если вы сделаете is
проверка, за которой следует полное приведение (либо as
cast или с помощью классического оператора приведения), вы эффективно выполняете is
проверьте дважды, что приводит к небольшим дополнительным накладным расходам.
Другие советы
Я узнал, что это:
if (obj is Foo) {
Foo f = (Foo)obj;
f.doSomething();
}
медленнее, чем это:
Foo f = obj as Foo;
if (f != null) {
f.doSomething();
}
Достаточно ли медленно, чтобы иметь значение?Вероятно, нет, но это настолько простая вещь, на которую стоит обратить внимание, что вы с таким же успехом могли бы это сделать.
«is» по сути эквивалентен IL-оператору «isinst», который в этой статье описан как быстрый.
Это должно быть достаточно быстро, чтобы не иметь значения.Если вы проверяете тип объекта настолько, чтобы он оказал заметное влияние на производительность, вам необходимо переосмыслить свой дизайн.