Quais são as características de desempenho da reflexão 'is' em C#?[duplicado]
-
09-06-2019 - |
Pergunta
Essa pergunta já tem resposta aqui:
- Desempenho do operador C# 'is' 8 respostas
Isso é mostrando que a conversão de 'como' é muito mais rápida que a conversão de prefixo, mas e a reflexão de 'é'?Quão ruim é isso?Como você pode imaginar, pesquisar por 'é' no Google não é muito eficaz.
Solução
Existem algumas opções:
- O elenco clássico:
Foo foo = (Foo)bar
- O
as
operador de elenco:Foo foo = bar as Foo
- O
is
teste:bool is = bar is Foo
- O elenco clássico precisa verificar se
bar
pode ser lançado com segurança paraFoo
(rápido) e então faça isso (mais lento) ou lance uma exceção (muito lento). - O
as
operador precisa verificar sebar
pode ser lançado, então faça o lançamento, ou se não puder ser lançado com segurança, então ele simplesmente retornanull
. - O
is
operador apenas verifica sebar
pode ser lançado para Foo e retornar umboolean
.
O is
test é rápido porque faz apenas a primeira parte de uma operação completa de fundição.O as
operador é mais rápido que uma conversão clássica porque não lança uma exceção se a conversão falhar (o que o torna bom para situações em que você espera legitimamente que a conversão possa falhar).
Se você só precisa saber se a variável bar
é um Foo
então use o is
operador, MAS, se você for testar se bar
é um Foo
, e se, então lance-o, então você deve usar o as
operador.
Essencialmente, todo elenco precisa fazer o equivalente a um is
verifique internamente para começar, para garantir que a conversão é válida.Então se você fizer um is
verificação seguida por um elenco completo (seja um as
cast, ou com o operador cast clássico) você está efetivamente fazendo o is
verifique duas vezes, o que é uma pequena sobrecarga extra.
Outras dicas
A maneira como aprendi é que:
if (obj is Foo) {
Foo f = (Foo)obj;
f.doSomething();
}
é mais lento que isso:
Foo f = obj as Foo;
if (f != null) {
f.doSomething();
}
É lento o suficiente para importar?Provavelmente não, mas é uma coisa tão simples de prestar atenção que você também pode fazer isso.
"is" é basicamente equivalente ao operador IL "isinst" - que esse artigo descreve como rápido.
Deve ser rápido o suficiente para não importar.Se você está verificando o tipo de um objeto o suficiente para causar um impacto perceptível no desempenho, você precisa repensar seu design