typeof
se aplica a un nombre de tipo conocido en tiempo de compilación. También se puede aplicar a parámetros de tipo genérico. GetType
se aplica a un objeto en tiempo de ejecución. En ambos casos, el resultado es un objeto del tipo System.Type
que contiene metainformación sobre un tipo.
Si tiene
string s = "hello";
Estas dos líneas son válidos
Type t1 = typeof(string);
Type t2 = s.GetType();
Y esta comparación rendimientos true
t1 == t2 ==> true
Pero
object obj = "hello";
Estas dos líneas son válidos
Type t1 = typeof(object);
Type t2 = obj.GetType(); // ==> string!
Y esta comparación rendimientos false
t1 == t2 ==> false
es decir, el tipo de tiempo de compilación (tipo estático) de la variable obj
no es el mismo que el tiempo de ejecución tipo (el tipo dinámico) del objeto al que hace referencia el obj
. (Aquí "dinámica" no tiene nada que ver con la palabra clave dynamic
!)
tipos de pruebas
Sin embargo, si sólo desea saber si mycontrol
es una TextBox
A continuación, puede probar
if (mycontrol is TextBox)
Tenga en cuenta que esto no es completamente equivalente a
if (mycontrol.GetType() == typeof(TextBox))
porque mycontrol
podría tener un tipo que se deriva de TextBox
. En ese caso, la primera comparación produce true
y la segunda false
! La primera y más fácil variante está bien en la mayoría de los casos, ya que un control derivado de TextBox
hereda todo lo que tiene TextBox
, probablemente le agregue más y por lo tanto es compatible con TextBox
.
public class MySpecializedTextBox : TextBox
{
}
MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox) ==> true
if (specialized.GetType() == typeof(TextBox)) ==> false
casting
Si ha seguido la siguiente prueba por un elenco y T es anulable ...
if (obj is T) {
T x = (T)obj; // The casting tests, whether obj is T again!
...
}
... se puede cambiar a. ..
T x = obj as T;
if (x != null) {
...
}
La prueba de si un valor es de un tipo determinado y la conversión (que implica esta misma prueba de nuevo) puede llevar mucho tiempo para cadenas de herencia largas. Usar el operador as
seguido de una prueba para null
es más efectivo.
Comenzando con C# 7.0 se puede simplificar el código mediante el uso de la coincidencia de patrones:
if (obj is T t) {
// t is a variable of type T
...
}
¿Qué quiere decir por esto funciona ... y esto no ...? –
@ anouar204: pruébelas en su IDE. –
No 'compilar' sería más apropiado que does not' work' –