Compruebe si la instancia es de un tipo

181

Usar esto para verificar si ces una instancia de TForm.

c.GetType().Name.CompareTo("TForm") == 0

¿Hay alguna forma más segura de hacerlo además de usar a stringcomo parámetro CompareTo()?

Lennie
fuente
20
Ciertamente espero que tampoco lo hagas en Java de esa manera. Java instanceofy C # isson formas mucho mejores de hacerlo.
Powerlord

Respuestas:

410

Las diferentes respuestas aquí tienen dos significados diferentes.

Si desea verificar si una instancia es del tipo exacto, entonces

if (c.GetType() == typeof(TForm))

Es el camino a seguir.

Si desea saber si ces una instancia TForm o una subclase , use is/ as:

if (c is TForm)

o

TForm form = c as TForm;
if (form != null)

Vale la pena tener claro en su mente cuál de estos comportamientos realmente desea.

Jon Skeet
fuente
77
Una pequeña nota: use "es" si no quiere usar el resultado del lanzamiento y use "como" si lo hace.
Aviram Fireberger
14
Con C # 7 puede combinarse isy combinar aspatrones:if (x is TForm tf) {…
Richard
39
if(c is TFrom)
{
   // Do Stuff
}

o si planea usarlo ccomo a TForm, use el siguiente ejemplo:

var tForm = c as TForm;
if(tForm != null)
{
   // c is of type TForm
}

El segundo ejemplo solo necesita verificar si ces de tipo TFormuna vez. Si verifica si ces de tipo y TFormluego lo lanza, el CLR se somete a una verificación adicional. Aquí hay una referencia .

Editar: Robado de Jon Skeet

Si desea asegurarse de que ces de TFormy no de ninguna clase que hereda TForm, use

if(c.GetType() == typeof(TForm))
{
   // Do stuff cause c is of type TForm and nothing else
}
Cartero
fuente
10

Además, algo en la misma línea

Type.IsAssignableFrom(Type c)

"Verdadero si c y el Tipo actual representan el mismo tipo, o si el Tipo actual está en la jerarquía de herencia de c, o si el Tipo actual es una interfaz que implementa c, o si c es un parámetro de tipo genérico y el Tipo actual representa una de las restricciones de c ".

Desde aquí: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx

Brad Cunningham
fuente
Este es también mi favorito personal. typeof(Class).IsAssignableFrom(object.getType())similar al instanceofoperador de Java .
SkidRunner
¿Da falso si no están en la misma rama de la jerarquía de herencia pero existe un operador de conversión?
Paul Stelian
Buena pregunta @PaulStelian. No estoy seguro de lo mejor de mi cabeza, pero supongo que devolvería un falso en esa situación. Al menos ese sería mi comportamiento esperado. Posiblemente, si existe una conversión implícita, podría ser verdadera, pero eso sería extraño.
Brad Cunningham el
¿Alguien que tenga instalado Visual Studio para probarlo?
Paul Stelian
1
@PaulStelian: devuelve falso. Esto se puede ver siguiendo el enlace del documento y observando que no se mencionan las conversiones. Otra forma de pensarlo es que se T1.IsAssignableFrom(T2)devuelve trueen situaciones en las asque el operador devuelve un valor no nulo, dadas instancias de esos tipos.
ToolmakerSteve
9

Un poco más compacto que las otras respuestas si desea utilizar c como TForm:

if(c is TForm form){
    form.DoStuff();
}
Ali Rahman
fuente
3

Intenta lo siguiente

if (c is TForm) { 
 ...
}
JaredPar
fuente
2

Como otros han mencionado, la palabra clave "es". Sin embargo, si luego lo va a lanzar a ese tipo, por ejemplo.

TForm t = (TForm)c;

Entonces deberías usar la palabra clave "as".

p.ej TForm t = c as TForm.

Entonces puedes verificar

if(t != null)
{
 // put TForm specific stuff here
}

No combine como es porque es una verificación duplicada.

taylonr
fuente
0

O

c.getType() == typeOf(TForm)
Raynos
fuente
-1
bool isValid = c.GetType() == typeof(TForm) ? true : false;

o más simple

bool isValid = c.GetType() == typeof(TForm);
Gabe
fuente
En mi humilde opinión: evitaría una compasión directa (es decir ==). En objetos o lenguajes orientados que admitan la herencia a menos que sepa que su Tipo específico nunca se heredará, por ejemplo, de una sealedClase. Además: el uso de un operador ternario que devuelve valores booleanos (estáticos / constantes) me molesta, me molestaría menos si fuera una switchdeclaración.
SkidRunner