【发布时间】:2011-06-14 10:54:09
【问题描述】:
int i=1;
long longOne=i; //assignment works fine
//...but
bool canAssign=(typeof(long).IsAssignableFrom(typeof(int))); //false
为什么canAssign 是假的?
【问题讨论】:
int i=1;
long longOne=i; //assignment works fine
//...but
bool canAssign=(typeof(long).IsAssignableFrom(typeof(int))); //false
为什么canAssign 是假的?
【问题讨论】:
因为 Type.IsAssignableFrom 是一种 .NET 框架工具,而从 int 分配到 long 是一种 C# 语言。如果您查看生成的 IL,您将在那里看到类型转换指令。 CLR 规则在很多地方可能与 C# 不同,还有一个例子是 MethodBase.Invoke 中的重载解析和 C# 编译器执行的重载解析。
【讨论】:
IsAssignableFrom 如果类型相同,或者类型实现或继承它,则返回 true。
long 不继承 int,因此该方法返回 false。
当您将 int 值分配给 long 时,它不仅仅是一个赋值。编译器还会自动添加代码以将int 值转换为long 值。
【讨论】:
来自http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx:
如果 c 和当前 Type 表示相同的类型,或者如果当前 Type 在 c 的继承层次结构中,或者如果当前 Type 是 c 实现的接口,或者如果 c 是泛型类型参数并且current Type 表示 c 的约束之一。如果这些条件都不为真,或者 c 为空,则为假。
正如@BoltClock 所说,这只是隐式转换。
【讨论】:
var isSameOrChild = baseType.IsAssignableFrom(otherType)
查看 Reflector 中的方法,似乎该方法用于确定继承而不是兼容性。
例如,如果您有一个实现接口的类,那么如果您这样做了,该方法将返回 true
(typeof(interface).IsAssignableFrom(typeof(class))
【讨论】:
当您将int 分配给long 时,所发生的只是隐式转换。 longOne 是一个实际的 long(就好像你将它初始化为 1L),而不是伪装成 long 的 int,如果你明白了。
即int(或Int32)和long(或Int64)在继承或实现方面不相关;它们恰好是可转换的,因为它们都是整数类型。
【讨论】: