Cómo comprobar si el tipo de variable coincide con el tipo almacenado en una variable

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

u is User -> returns true

u is t -> compilation error

¿Cómo pruebo si alguna variable es de algún tipo de esta manera?

Karan
fuente

Respuestas:

194

Todas las otras respuestas contienen omisiones significativas.

El isoperador no comprueba si el tipo de tiempo de ejecución del operando es exactamente el tipo dado; más bien, comprueba si el tipo de tiempo de ejecución es compatible con el tipo dado:

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.

Pero la verificación de la identidad del tipo con la reflexión comprueba la identidad , no la compatibilidad

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 

Si eso no es lo que desea, probablemente desee 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
fuente
4
Si bien el enfoque final que se muestra aquí funciona, es innecesariamente detallado. typeof(Animal).IsInstanceOfType(x)es más corto y sencillo que typeof(Animal).IsAssignableFrom(x.GetType());(y Resharper sugerirá usar el primero si usa el segundo).
Mark Amery
ACLARACIÓN: para responder a la pregunta original, sustituir ta typeof(Animal). Entonces la forma mejorada de Mark se convierte en t.IsInstanceOfType(x).
ToolmakerSteve
13

GetType() existe en cada tipo de marco, porque está definido en la base object tipo . Entonces, independientemente del tipo en sí, puede usarlo para devolver el subyacenteType

Entonces, todo lo que necesitas hacer es:

u.GetType() == t
Dave Bish
fuente
1
En realidad, la respuesta de Eric es útil y todo, pero no responde a la pregunta real de cómo realizar una prueba con un tipo desconocido en la forma "u is t" descrita en la pregunta original, y la suya sí.
Daniel
@Daniel - No exactamente. La respuesta de Dave solo es correcta si desea excluir subclases de t. La respuesta de Eric explica principalmente qué hacer; sólo falta una aclaración de dónde poner "t". Agregaré un comentario allí.
ToolmakerSteve
10

Necesita ver si el Tipo de su instancia es igual al Tipo de la clase. Para obtener el tipo de instancia, usa el GetType()método:

 u.GetType().Equals(t);

o

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

Deberías hacerlo. Obviamente, podría usar '==' para hacer su comparación si lo prefiere.

Sam Holder
fuente
+1 Pero prefiera la segunda opción. u.GetType.Equals(typeof(User));
Omar
Una razón por la que esto es menos seguro que usar == es que si GetType () de alguna manera devuelve null, arrojará.
Dave Bish
1
@Fuex, sí, creo que hace que el código sea más fácil de leer si el typeof está en línea, por eso lo publiqué así, aunque en el ejemplo de OPs ya tiene una variable tque contiene el tipo.
Sam Holder
@DaveBish si GetType devolviera nulo, entonces me preocuparía que muchas cosas comenzaran a arrojar ... pero punto, por supuesto que tiene razón
Sam Holder
@SamHolder Sí: la única situación en la que esto sucedería sería si alguien anulara un tipo base y arruinara la implementación de alguna manera. Sería extraño, seguro.
Dave Bish
4

Para comprobar si un objeto es compatible con una variable de tipo determinada, en lugar de escribir

u is t

Deberías escribir

typeof(t).IsInstanceOfType(u)
Mantas Janulionis
fuente
1
¿Cuál es el beneficio de la sintaxis más detallada frente a la sintaxis 'u is t'?
Kyle Humfeld
@KyleHumfeld Si tuvieras Type foo; Objeto A; no puedes escribir "A es foo", pero puedes escribir foo.isInstanceOfType (A)
Timur Nuriyasov