检查类型TA是否可以在运行时强制转换为TB? (考虑的不仅仅是inheritance)

所以我知道这有效:

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。

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

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

一方面注意,因为您的示例特别提到了原始值类型,请注意隐含的“转换”(在C#中)的存在并不意味着所有“强制转换”都可以工作。 C#强制转换操作(T)x也可以表示’将x中的值解包为类型T’。 如果x包含一个盒装的Int32并且您尝试(Int64)x,那么这将在运行时失败,即使您可以隐式地将Int32“转换”为Int64。 有关拆箱工作原因的详细信息,请参阅Eric Lippert 。

一种(不太优雅)的方法是简单地尝试它 – 将您的尝试包装在try / catch中,如果捕获exception,则返回Assert false。