2012-07-03 19 views
25

Por qué esto funciona¿Cuándo y dónde usar GetType() o typeof()?

if (mycontrol.GetType() == typeof(TextBox)) 
{} 

y esto no lo hacen?

Type tp = typeof(mycontrol); 

Pero esto funciona

Type tp = mycontrol.GetType(); 

Yo mismo uso is operador para chequear el tipo de falla pero mi entendimiento cuando uso typeof() y GetType()

Dónde y cuándo utilizar GetType() o typeof()?

+1

¿Qué quiere decir por esto funciona ... y esto no ...? –

+1

@ anouar204: pruébelas en su IDE. –

+4

No 'compilar' sería más apropiado que does not' work' –

Respuesta

61

typeof es un operador para obtener un tipo conocido en 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). Vea el C# language specification para más detalles.

GetType() es un método que llama en objetos individuales, para obtener el tipo tiempo de ejecución del objeto.

Nota que a menos que sólo se quiere exactamente los casos de TextBox (más que instancias de subclases) que normalmente tendría que utilizar:

if (myControl is TextBox) 
{ 
    // Whatever 
} 

O

TextBox tb = myControl as TextBox; 
if (tb != null) 
{ 
    // Use tb 
} 
+2

Su línea ''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)' 'es la respuesta perfecta a mi pregunta. Gracias por ayudarme. –

5

puede que le resulte más fácil use el is keyword:

if (mycontrol is TextBox) 
+0

Esta es la respuesta que estoy encontrando en todos los SO y sé esto. –

+5

@NikhilAgrawal: si ya sabe algo que es una respuesta obvia a su pregunta, debe decirlo en la pregunta para evitar perder el tiempo de la gente. Por favor, lea http://tinyurl.com/so-hints –

+1

@JonSkeet: uso es palabra clave, pero me quedé desconcertado en typeof() y GetType() –

7

typeOf es una palabra clave C# que se usa cuando tiene el nombre de la clase. Se calcula en tiempo de compilación y, por lo tanto, no se puede usar en una instancia, que se crea en tiempo de ejecución. GetType es un método de la clase de objeto que se puede usar en una instancia.

23

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 
    ... 
} 
Cuestiones relacionadas