Como verificar se o tipo da variável corresponde ao tipo armazenado em uma variável

96
User u = new User();
Type t = typeof(User);

u is User -> returns true

u is t -> compilation error

Como faço para testar se alguma variável é de algum tipo dessa maneira?

Karan
fonte

Respostas:

194

Todas as outras respostas contêm omissões significativas.

O isoperador não verifica se o tipo de tempo de execução do operando é exatamente o tipo fornecido; em vez disso, ele verifica se o tipo de tempo de execução é compatível com o tipo fornecido:

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

Mas verificar a identidade do tipo com verificações de reflexão de identidade , não de compatibilidade

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false! even though x is an animal

or with the type variable
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false! even though x is an 

Se não for isso que você deseja, provavelmente deseja IsAssignableFrom:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true! A variable of type Animal may be assigned a Tiger.

or with the type variable
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true! A 
Eric Lippert
fonte
4
Embora a abordagem final mostrada aqui funcione, é desnecessariamente detalhada. typeof(Animal).IsInstanceOfType(x)é mais curto e mais direto do que typeof(Animal).IsAssignableFrom(x.GetType());(e Resharper irá sugerir o uso do primeiro se você usar o último).
Mark Amery
ESCLARECIMENTO: para responder à pergunta original, substituir tpor typeof(Animal). Então a forma melhorada de Mark se torna t.IsInstanceOfType(x).
Toolmaker Steve
13

GetType()existe em cada tipo de estrutura, porque é definido no objecttipo base . Portanto, independentemente do tipo em si, você pode usá-lo para retornar o subjacenteType

Então, tudo que você precisa fazer é:

u.GetType() == t
Dave Bish
fonte
1
Na verdade, a resposta de Eric é útil e tudo, mas não responde à questão real de como testar com um tipo desconhecido da maneira "u é t" descrita na questão original, e a sua responde.
Daniel
@Daniel - Não exatamente. A resposta de Dave só está correta se você quiser excluir as subclasses de t. A resposta de Eric explica principalmente o que fazer; está faltando apenas um esclarecimento de onde colocar "t". Vou adicionar um comentário lá.
Toolmaker Steve
10

Você precisa ver se o Type da sua instância é igual ao Type da classe. Para obter o tipo de instância, você usa o GetType()método:

 u.GetType().Equals(t);

ou

 u.GetType.Equals(typeof(User));

deve fazer isso. Obviamente, você pode usar '==' para fazer sua comparação, se preferir.

Sam Holder
fonte
+1 Mas prefira a segunda escolha. u.GetType.Equals(typeof(User));
Omar
Uma razão pela qual isso é menos seguro do que usar == - é que se GetType () de alguma forma retornar nulo - ele será lançado.
Dave Bish
1
@Fuex, sim eu, acho que torna o código mais fácil de ler se o typeof for inline, por isso postei assim, mesmo que no exemplo dos OPs ele já tenha uma variável tque contém o tipo.
Sam Holder
@DaveBish se GetType retornou null, então eu ficaria preocupado se muitas coisas começassem a acontecer ... mas, ponto tomado, você está certo, é claro
Sam Holder
@SamHolder Sim - A única situação em que isso aconteceria seria se alguém substituísse um tipo de base e estragasse a implementação de alguma forma. Seria estranho, com certeza.
Dave Bish
4

Para verificar se um objeto é compatível com um determinado tipo de variável, ao invés de escrever

u is t

você deveria escrever

typeof(t).IsInstanceOfType(u)
Mantas Janulionis
fonte
1
Qual é a vantagem de uma sintaxe mais detalhada em comparação com a sintaxe "u is t"?
Kyle Humfeld
@KyleHumfeld Se você tivesse Type foo; Objeto A; você não pode escrever "A é foo", mas pode escrever foo.isInstanceOfType (A)
Timur Nuriyasov