检查型TA可以投在运行时类型结核病? (考虑到比继承更多的东西)结核病、考虑到、东西、类型

2023-09-03 17:09:11 作者:雨中的恋人

所以我知道这个工作的:

So I know that this works:

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的。

However, let's say those two types were Int32 and Int64.

在运行时,我可以投一个Int32值,为Int64的变量,而不是周围的其他方式。如何检查这种铸造兼容性在运行时? (IsAssignableFrom这个是不行的,它总是提供虚假的的Int32和Int64的)

At runtime, I can cast an Int32 value to an Int64 variable, but not the other way around. How can I check this kind of casting-compatibility at runtime? (IsAssignableFrom doesn't work for this, it always gives false for Int32 and Int64)

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

I cannot simply try to cast, because I don't have any value of those types, I'm asking the hypothetical scenario of having two types A and B, not having two values a and b.

推荐答案

对于非原生类型,可以反映出,检查是否存在对两种类型的 op_Implicit 方法支撑的转换。 IL实际上并不支持真正的运算符重载,所以它是一个纯粹的约定系统的C#识别运算符重载。该方法也将被打上IsSpecialName,如果它是从C#中运算符重载定义创建。

For non-primitive types, you can reflect and inspect whether there is an op_Implicit method on either type supporting the conversion. IL doesn't actually support true operator overloading, so it's purely a convention system for C# to recognize the operator overloads. The method will also be marked IsSpecialName if it was created from an operator overload definition in C#.

有关基本类型(如的Int32和Int64的),最简单的选择是C中的各种情况很难$ C $,作为转换是通过原语IL运code,而不是通过一个方法。目前只有极少数原始类型,虽然,所以它不会是很难创建的检查每个原始类型所有可能的方法。

For primitive types (like Int32 and Int64), the simplest option is to hardcode the various cases, as conversion is via a primitive IL opcode rather than via a method. There are only a handful of primitive types, though, so it wouldn't be difficult to create a method with the check for all possibilities for each primitive type.

一个侧面说明,因为你的例子提到的原始值类型明确,注意,一个隐含的'转换'(在C#)的存在并不意味着所有的投射将起作用。 C#的转换操作(T)X 也可以指拆箱x中键入T的值。如果x包含一个盒装的Int32并尝试(Int64的)X,这样会在运行时失败,即使你可以隐式'转换'一个Int32为Int64。请参见埃里克利珀了解详情至于为什么拆箱以这种方式工作。

One side note since your example mentioned primitive value types specifically, note that the existence of an implicit 'conversion' (in C#) does not mean that all 'casts' will work. The C# cast operation (T)x can also mean 'unbox the value in x to type T'. If x contains a boxed Int32 and you attempt to (Int64)x, this will fail at runtime, even though you can implicitly 'convert' an Int32 to an Int64. See Eric Lippert for more information as to why unboxing works this way.