2011-04-20 9 views
64

yo estaba tratando de hacer algunas pruebas Convención hoy, y conseguir todos los tipos en un conjunto (llamando Assembly.GetTypes()), cuando tropecé en algo:¿Cuál es la diferencia entre System.Type y System.RuntimeType en C#?

System.RuntimeType:[First.Namespace.FirstClass] 

Siempre que trato de comparar ese tipo con typeof(FirstClass), se no son iguales Entonces, cuando trato de encontrar todos los tipos que contienen FirstClass como un parámetro genérico, no encuentro ninguno.

¿Cuál es la diferencia entre System.RuntimeType y System.Type?

¿Hay alguna manera de resolver mi problema?

+6

¿Puede proporcionar un pequeño programa que demuestre el problema que está experimentando? –

+0

Iba a ir, pero ya recibí la respuesta: P –

Respuesta

79

System.RuntimeType es una clase concreta que se deriva de la clase base abstracta System.Type. Como System.RuntimeType no es público, generalmente encontrará instancias de él como System.Type.

Puede haber confusión cuando intenta obtener el tipo de un objeto y, erróneamente, llamar a GetType() en otro objeto que representa el tipo del primer objeto, en lugar de simplemente usar ese objeto directamente. Entonces Type.ToString() regresará "System.RuntimeType" cuando el objeto se le llama en es representativos de una categoría:

string str = string.Empty; 
Type strType = str.GetType(); 
Type strTypeType = strType.GetType(); 
strType.ToString();  // returns "System.string" 
strTypeType.ToString(); // returns "System.RuntimeType" 

Por ejemplo, en this blog post alguien está tratando de obtener el tipo de una columna en una base de datos, hacer algo como esto:

object val = reader.GetFieldType(index); 
Type runtimeType = val.GetType(); 
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType"); 
Type type = (Type)propInfo.GetValue(val, null); 

Dado que val ya es un objeto Type, val.GetType() devolverá otro tipo de objeto que represente el tipo System.RuntimeTime ya que este es el tipo concreto utilizado para representar el objeto tipo original. La entrada de blog a continuación, se muestran algunos trucos reflexión innecesaria, para obtener el tipo del objeto de tipo original, fue cuando realmente todo lo que se requería:

Type type = reader.GetFieldType(index) as Type; 

Así que si su objeto Type informa que representa un System.RuntimeType, asegúrese no ha llamado accidentalmente al GetType() en un tipo que ya tiene.

+0

El primer fragmento de código solo comprueba si el objeto es una instancia de 'Type'; devolverá true incluso si pasa' typeof (int) '. El segundo fragmento de código no funciona para comparar 'typeof (string) .GetType()' y 'typeof (Type)'. –

+0

¡Esto es exactamente lo que estaba buscando! Encontré la publicación de Thomas Danecker pero no la de Doogal Bell en –

+1

@Mark Cidade. Bien visto, gracias. He reparado la respuesta para ser más útil, con la esperanza de aclarar cualquier confusión que introduje al citar esa publicación en el blog. – Ergwun

2

De la respuesta a Different between System.Type and System.RuntimeType por Thomas Danecker:

System.Type es una clase base abstracta. El CLR tiene su implementación concreta en el tipo interno System.RuntimeType. Debido a esto, typeof (string) .GetType() devuelve RuntimeType pero typeof (Type) devuelve Type normal. El uso del método .Equals hace de hecho un object.ReferenceEquals que devuelve falso. Para obtener los resultados de espera , puede usar el tipo .IsInstanceOfType (elemento). Este también devolverá verdadero si el elemento es de un tipo derivado. Si desea verificar para el tipo exacto, el valor de retorno de falso de su método es el resultado deseado . También puede usar checkType (arrayType, Type.GetType ("System.RuntimeType")) en para RuntimeType.

0

En breve ...

"".GetType().ToString()   == "System.String" 

    "".GetType().GetType().ToString() == "System.RuntimeType" 

La forma en que ahora pienso en ello es que System.Type es un tipo base para la tipo que representa los resultados de solicitud de tipo de objeto en el tiempo de ejecución, es decir, System.RuntimeType. Entonces, cuando solicita el tipo de un objeto, como en, "".GetType(), la instancia de System.Type devuelta es su descendiente, System.RuntimeType. De hecho, uno debe esperar que el typeof(System.Type).GetType() también sea System.RuntimeType, pero creo que el marco evita específicamente esta ... simetría.

Cuestiones relacionadas