4

所以我知道这有效:

class A
{
}
class B : A
{       
}

[Test]
public void CanCast()
{
    Assert.That(typeof(A).IsAssignableFrom(typeof(B)));
    Assert.That(!typeof(B).IsAssignableFrom(typeof(A)));
}

但是,假设这两种类型是 Int32 和 Int64。

在运行时,我可以将 Int32 值转换为 Int64 变量,但反过来不行。如何在运行时检查这种类型的转换兼容性?(IsAssignableFrom 对此不起作用,它总是为 Int32 和 Int64 给出 false)

编辑:我不能简单地尝试转换,因为我没有这些类型的任何值,我问的是有两种类型 A 和 B,没有两个值 a 和 b 的假设场景。

4

2 回答 2

6

对于非原始类型,您可以反映和检查op_Implicit任一类型上是否存在支持转换的方法。IL 实际上并不支持真正的运算符重载,因此它纯粹是 C# 识别运算符重载的约定系统。如果该方法是从 C# 中的运算符重载定义创建的,则该方法也将被标记为 IsSpecialName。

对于原始类型(如 Int32 和 Int64),最简单的选择是对各种情况进行硬编码,因为转换是通过原始 IL 操作码而不是通过方法进行的。但是,只有少数原始类型,因此创建一个检查每种原始类型的所有可能性的方法并不难。

附带说明,因为您的示例特别提到了原始值类型,请注意隐式“转换”(在 C# 中)的存在并不意味着所有“转换”都可以工作。C# 转换操作(T)x也可以表示“将 x 中的值拆箱为类型 T”。如果 x 包含一个装箱的 Int32 并且您尝试 (Int64)x,这将在运行时失败,即使您可以将 Int32 隐式“转换”为 Int64。请参阅Eric Lippert以获取有关拆箱为何以这种方式工作的更多信息。

于 2012-10-05T21:25:56.603 回答
-1

一种(不太优雅的)方法是简单地尝试它 - 将您的尝试包装在 try/catch 中,如果您捕获到异常则断言为 false。

于 2012-10-05T15:30:19.953 回答