2010-09-05 11 views
8

Imagine que le han dado dos tipos de System.Type y desea determinar si hay una conversión de tipo implícita o explícita de uno a otro.Comprobando si un tipo admite una conversión de tipo implícita o explícita a otro tipo con .NET

Sin comprobar específicamente los métodos estáticos ¿existe un método integrado para determinar si el tipo admite cualquiera de estas conversiones?

Sé que este es un cuerpo breve para una pregunta, pero creo que el escenario es relativamente fácil de explicar, avíseme si no.

Gracias de antemano, Stephen.

+0

¿Qué quiere decir con 'conversión de tipo' - asignabilidad de instancias o convertibilidad en el sentido 'TypeConverter'? –

+0

Específicamente, los operadores implícitos/explícitos escritos de C# (vea http://msdn.microsoft.com/en-us/library/z5z9kes2(VS.71).aspx y http://msdn.microsoft.com/en-us/ library/xhbhezf4 (VS.71) .aspx) – meandmycode

+0

posible duplicado de [¿Cómo comprobar si existe un molde implícito o explícito?] (http://stackoverflow.com/questions/1815452/how-to-check-if-implicit- or-explicit-cast-exists) – nawfal

Respuesta

8

Expression.Convert puede buscar un operador de conversión definido por el usuario, pero desafortunadamente lanzará una excepción si no se encuentra ninguno. Podría usarlo así:

public static bool CanConvert(Type fromType, Type toType) 
{ 
    try 
    { 
     // Throws an exception if there is no conversion from fromType to toType 
     Expression.Convert(Expression.Parameter(fromType, null), toType); 
     return true; 
    } 
    catch 
    { 
     return false; 
    } 
} 
+0

¡Gracias Quartermeister esto es definitivamente una solución! – meandmycode

+2

@meandmycode: si desea implementar lo mismo sin la sobrecarga de una excepción, puede ejecutar Reflector en Expression.Convert para ver exactamente lo que hace. Los métodos interesantes son HasIdentityPrimitiveOrNullableConversion, HasReferenceConversion y GetUserDefinedCoercionMethod en System.Dynamic.Utils.TypeUtils. – Quartermeister

+0

Bien, gracias por el esfuerzo de investigación, no estoy completamente en contra de evitar su código sugerido, incluso si implemento los métodos como TypeUtils puede terminar siendo más trabajo para mantener eso que capturar simplemente la excepción. – meandmycode

0

Usted podría tratar de fundición cada una a la otra y agarrar la excepción

+0

Desafortunadamente, solo tengo acceso al objeto Type, no a los objetos reales, así que no podría hacer esto. – meandmycode

0

creo Type.IsAssignableFrom debería darle lo que necesita.

[editar] tenga en cuenta que esto NO considera los operadores de conversión, por lo que es posible que esto no sea útil para usted. Vale la pena mencionar de todos modos.

+0

Eso no tomará en consideración ningún operador de conversión personalizado. Solo mira la jerarquía de tipos. – driis

+0

No estoy seguro de que maneje los operadores de conversión de tipo implícito/explícito que puede definir con C#. Por ejemplo, si escribo typeof (XName) .IsAssignableFrom (typeof (string)) obtengo false. Pero XName tiene una conversión de tipo implícita de cadena. – meandmycode

7

No lo creo. Tendrá que usar el reflejo y buscar los buenos métodos op_Implicit y op_Explicit estáticos en cada tipo.

Esto nos lleva a la pregunta muy interesante: el que tiene un mayor impacto en el rendimiento, reflexión (esta respuesta) o el uso de excepciones para el flujo de control (Quartermeister's)? Honestamente, no pude adivinar. Es posible que desee perfilar cada uno y descubrir por ti mismo.

+0

Eep, tal vez esto no es tan malo, me preocupaba que buscar estos métodos especialmente nombrados era frágil, pero, por otro lado, ¡nunca esperaría que estos nombres de métodos cambiaran! – meandmycode

+0

@meandmycode: Sí, no estoy seguro de si están o no especificados; pero pienso que están en la misma categoría que los métodos 'get_' y' set_' para las propiedades - * muy * improbables de cambiar (aunque comparto tu incomodidad con un enfoque "bajo la tapa"). –

+0

No estoy 100% seguro, pero cerca de :) Creo que se perderá algunas conversiones en compilación si solo está buscando estos métodos, como int a long y derivadas a base/interface. Shich aumentaría la fragilidad de la solución ya que otros cambios además del cambio del nombre del método serían un cambio radical –

Cuestiones relacionadas