c# - namespace - ¿Cuándo y dónde usar GetType() o typeof()?
typeof generic class c# (4)
Esta pregunta ya tiene una respuesta aquí:
Por qué esto funciona
if (mycontrol.GetType() == typeof(TextBox))
{}
y esto no?
Type tp = typeof(mycontrol);
Pero esto funciona
Type tp = mycontrol.GetType();
Yo mismo uso el operador para verificar el tipo pero mi entendimiento falla cuando uso typeof()
y GetType()
¿Dónde y cuándo usar GetType()
o typeof()
?
Puede que le resulte más fácil usar la palabra clave is
:
if (mycontrol is TextBox)
typeof
es un operador para obtener un tipo conocido en tiempo de compilación (o al menos un parámetro de tipo genérico). El operando de typeof
es siempre el nombre de un tipo o parámetro de tipo - nunca una expresión con un valor (por ejemplo, una variable). Consulte la especificación del lenguaje C # para más detalles.
GetType()
es un método que llama a objetos individuales para obtener el tipo de tiempo de ejecución del objeto.
Tenga en cuenta que a menos que solo desee instancias exactas de TextBox
(en lugar de instancias de subclases), generalmente usaría:
if (myControl is TextBox)
{
// Whatever
}
O
TextBox tb = myControl as TextBox;
if (tb != null)
{
// Use tb
}
typeof
se aplica a un nombre de tipo o parámetro de tipo genérico conocido en tiempo de compilación. GetType
se llama a un objeto en tiempo de ejecución. En ambos casos, el resultado es un objeto del tipo System.Type
contiene metainformación sobre un tipo.
Si usted tiene
string s = "hello";
Estas dos líneas son válidas
Type t1 = typeof(string);
Type t2 = s.GetType();
t1 == t2 ==> true
Pero
object obj = "hello";
Estas dos líneas son válidas
Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType(); // ==> string!
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 tipo de tiempo de ejecución (el tipo dinámico) del objeto referenciado por obj
. (Aquí "dinámico" no tiene nada que ver con la palabra clave dynamic
!)
Tipos de prueba
Sin embargo, si solo quieres saber si mycontrol
es un TextBox
entonces simplemente puedes 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 derivado de TextBox
. En ese caso, la primera comparación arroja true
y el segundo 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 agrega 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
Fundición
Si tiene la siguiente prueba seguida de un yeso y T es nulable ...
if (obj is T) {
T x = (T)obj; // The casting tests, whether obj is T again!
...
}
... puedes cambiarlo a ...
T x = obj as T;
if (x != null) {
...
}
Probar si un valor es de un tipo y fundición dados (lo que implica nuevamente esta misma prueba) puede llevar mucho tiempo para cadenas de herencia largas. Usar el operador as
seguido de una prueba de null
tiene más rendimiento.
Comenzando con C # 7.0 puedes simplificar el código usando la coincidencia de patrones:
if (obj is T t) {
// t is a variable of type T
...
}