2010-11-08 20 views
9

En algunas ocasiones distintas, he tratado de extraer el tipo declarado de una variable, relativamente lejos de su declaración, solo para descubrir que typeof(T) solo funciona con nombres de tipos.C# /. NET: ¿`typeof (variable)` es una función de idioma posible?

Me preguntaba si habría algún cambio de rotura para permitir typeof(variable) también.

Por ejemplo, con este código:

class Animal { /* ... */ } 
class Goat : Animal { /* ... */ } 

/* ... */ 

var g = new Goat(); 
Animal a = g; 

Console.WriteLine(typeof(Goat)); 
Console.WriteLine(typeof(Animal)); 
Console.WriteLine(g.GetType()); 
Console.WriteLine(a.GetType()); 

se obtiene algo así como:

cabra
Animal
cabra
cabra

por qué no es posible para hacer esto:

Console.WriteLine(typeof(g)); 
Console.WriteLine(typeof(a)); 

cabra
Animal

he dado la especificación de una mirada superficial, y no puedo encontrar ningún conflicto. Creo que aclararía la pregunta '¿Por qué este tipo?' cuando se usa el operador typeof.

Sé que el compilador es capaz, aquí. Una aplicación utilizando métodos de extensión es realmente trivial:

public static Type TypeOf<T>(this T variable) 
{ 
    return typeof(T); 
} 

Pero que se siente sucio, abusando del tipo de inferencia del compilador.

+0

¿Cómo desea utilizar este? ¿Y por qué no se puede hacer usando 'is'? –

+0

Primero, ¿tienes algo en contra de GetType()? En segundo lugar, su comportamiento de ejemplo de typeof (g) y typeof (a) es incorrecto. El tipo subyacente de a es, de hecho, Cabra (no Animal). –

+0

@ 0xA3: Me encuentro usando 'typeof' para reflexión e interoperabilidad. 'is' no te da acceso a todo eso. –

Respuesta

3

supongo que es permitido:

class Animal { } 

string Animal; 
Type t = typeof(Animal); // uh-oh! 
+2

Esto no es necesariamente un problema ... En su escenario, typeof() podría comportarse como cualquier otra referencia al símbolo Animal: la variable local gana. –

+0

Eso pasa todo, no veo una razón por la que esto debería ser un problema. Tome esto por ejemplo: 'var System = string.Empty; var b = System.Double.NaN; ' –

+0

Para ser justos, permitir esos nombres de variable ambiguos en primer lugar ya es un problema. Y él pudo reformular la pregunta para evitarla, p. "¿Por qué no tienen un método' GetDeclaredType() 'para obtener el tipo declarado, en lugar del tipo de tiempo de ejecución". –

0

Si simplemente está tratando de obtener el tipo de algo, sólo puede llamar a

Type t1 = myObject.GetType(); 

se debe dar a la conducta que desea.

+1

Eso no obtiene el tipo declarado, sino que obtiene el tipo más específico del objeto al que se hace referencia. El tipo declarado es, en esencia, invisible para el tiempo de ejecución, pero es útil para la reflexión. –

4

Creo que el problema aquí es que .GetType() es anterior a typeof(). Solía ​​haber un día en C# donde se tenía que hacer

"0".GetType() 

con el fin de obtener el tipo de cuerda (por ejemplo), hasta que nació typeof(). Creo que si el concepto hubiera sido parte del diseño del lenguaje original, entonces podría funcionar como usted lo describe. Debido a que typeof() es una introducción tardía al idioma, los diseñadores tuvieron que hacer una elección: Obsoleto/desaprobar/eliminar .GetType() (y en el proceso hacer muchos, muchos usos de él obsoletos), hacer typeof() se superponen en funcionalidad con GetType() (que es lo que estás preguntando), o hacen que el uso de typeof() no se solape con GetType(). Creo que las personas C# simplemente optaron por no superponer la funcionalidad (para mantener las cosas simples y claras), y así typeof() se restringió en la forma en que es hoy.

+0

Bastante, pero me gustaría saber de un diseñador de idiomas sobre ese proceso de decisión. –

+1

@gmagana: Su respuesta parece suponer que 'GetType' y' typeof' hacen cosas idénticas. Este no es el caso. –

+0

@ 0xA3: Bueno, la pregunta también, entonces. Todo lo que digo es que, desde un punto de vista determinado, la decisión de no superponerse en la funcionalidad tiene sentido, como señala John, sería interesante ver cuál fue el proceso de decisión real cuando se introdujo typeof() en el idioma. ... –

0

usted parece estar haciendo dos preguntas diferentes aquí, el primero es por qué no hay operador para encontrar el tipo de variable declarada, y el otro preguntando ¿por qué no typeof (o) ser el equivalente de o. GetType().

Para el primero, la razón es porque no sirve para nada, el tipo declarado de una variable es por definición siempre conocido en tiempo de compilación. Agregar un operador no agregaría ningún valor.

Por el otro, el problema es que el uso de typeof (instancia) causa problemas con la resolución. Como Jason mencionó anteriormente, considere:

public class Animal {} 
string Animal; 
Type t = typeof(Animal); 

¿Qué es t? Si trata t como typeof (cadena), entonces acaba de agregar cambios masivos al idioma. Imagina todo el código que actualmente asume que t es un Animal, que actualmente es correcto.

Si tratas t como typeof (Animal), sin embargo, a continuación, el código es muy frágil. Imagine la situación en la que no existía la clase Animal cuando escribió el código, pero un año después alguien agregó una clase Animal en algún espacio de nombres que importó. Su código se rompería porque las reglas de resolución ahora usarían el tipo Animal en lugar de la variable local.

+1

No, no quiero 'typeof (o) 'ser equivalente a 'o.GetType()'. Eso no es ** en absoluto ** lo que quiero. Quiero que 'typeof (o)' sea una forma de encontrar el tipo declarado de 'o', equivalente a cómo' typeof (T) 'funciona en typename. Me doy cuenta de que hay conflictos de nombres, como dijo Jason, pero ¿por qué permitir conflictos de nombres en todo el lenguaje? –

+0

Una vez más, su argumento en contra de esto parecería apoyar la prohibición del uso de nombres de variables conflictivas en el espacio de nombres. Es por eso que existe la palabra clave 'global ::'. –

+1

@John, mencioné el problema "Obtener tipo declarado" en la primera parte de mi respuesta; no sirve para nada dado que el tipo declarado es conocido en tiempo de compilación. Por el momento, no sé si simplemente no ves el cambio o si crees que los cambios no son importantes. Su pregunta era si esto sería un cambio radical; la respuesta es sí. – tnyfst

Cuestiones relacionadas