int i=1;
long longOne=i; //assignment works fine
//...but
bool canAssign=(typeof(long).IsAssignableFrom(typeof(int))); //false
¿Por qué canAssign
es falso?No comprende Type.IsAssignableFrom
int i=1;
long longOne=i; //assignment works fine
//...but
bool canAssign=(typeof(long).IsAssignableFrom(typeof(int))); //false
¿Por qué canAssign
es falso?No comprende Type.IsAssignableFrom
Cuando asigna un int
a un long
, todo lo que ocurre es una conversión implícita. longOne
es un long
real (como si lo había inicializado como 1L
), y no un int
haciéndose pasar por un long
, si obtiene la deriva.
Es decir, int
(o Int32
) y long
(o Int64
) no están relacionadas en términos de herencia o aplicación; simplemente resultan convertibles porque ambos son tipos de números integrales.
Al observar el método en Reflector, parece que este método está destinado a ser utilizado para determinar la herencia en lugar de la compatibilidad.
Por ejemplo, si tiene una clase que implementa una interfaz entonces el método volvería cierto si usted hizo (typeof(interface).IsAssignableFrom(typeof(class))
De http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx:
cierto si c y el tipo de corriente representan el mismo tipo , o si el Tipo actual está en la jerarquía de herencia de c, o si el Tipo actual es una interfaz que c implementa, o si c es un parámetro de tipo genérico y el Tipo actual representa una de las restricciones de c. falso si ninguna de estas condiciones es verdadera, o si c es nulo.
Como @BoltClock dice que es solo una conversión implícita.
IsAssignableFrom
devuelve verdadero si los tipos son los mismos, o si el tipo lo implementa o lo hereda.
A long
no hereda int
, por lo que el método devuelve falso.
Cuando asigna un valor de int
a long
, no es solo una tarea. El compilador también agrega código automáticamente para convertir el valor int
en un valor de long
.
Porque Type.IsAssignableFrom es un recurso de .NET framework, mientras que la asignación de int a long es un lenguaje de C#. Si echas un vistazo a la IL generada verás la instrucción de conversión de tipo allí. Hay muchos lugares donde las reglas de CLR pueden diferir de las de C#, un ejemplo más es la resolución de sobrecarga en MethodBase.Invoke y la realizada por el compilador de C#.
Este siempre me confunde. Siempre me olvido de qué manera verificar (base a niño o niño a base). Dejando esto aquí: 'var isSameOrChild = baseType.IsAssignableFrom (otherType)' –