为什么typeof(IList <uint>)。IsAssignableFrom(typeof(int [])返回true?

时间:2018-04-23 09:35:57

标签: .net arrays reflection polymorphism

为什么以下断言失败(IsAssignableFrom返回true):

Assert.False(typeof(IList<UInt16>).IsAssignableFrom(typeof(Int16[])) Assert.False(typeof(IList<Int16>).IsAssignableFrom(typeof(UInt16[])) Assert.False(typeof(IList<UInt32>).IsAssignableFrom(typeof(Int32[])) Assert.False(typeof(IList<Int32>).IsAssignableFrom(typeof(UInt32[])) Assert.False(typeof(IList<UInt64>).IsAssignableFrom(typeof(Int64[])) Assert.False(typeof(IList<Int64>).IsAssignableFrom(typeof(UInt64[]))

我原以为它们会失败(IsAssignableFrom应该返回false),因为这会导致编译错误:

IList<UInt16> x = new Int16[]{}; // CS0029 Cannot implictly convert ...
IList<Int16> x = new UInt16[]{}; // CS0029 Cannot implictly convert ...
IList<UInt32> x = new Int32[]{}; // CS0029 Cannot implictly convert ...
IList<Int32> x = new UInt32[]{}; // CS0029 Cannot implictly convert ...
IList<UInt64> x = new Int64[]{}; // CS0029 Cannot implictly convert ...
IList<Int64> x = new UInt64[]{}; // CS0029 Cannot implictly convert ...

1 个答案:

答案 0 :(得分:1)

它是可分配的,因为如果你明确地强制转换它是有效的:

IList<UInt16> x = (IList<UInt16>)(IList)new Int16[] { };

所以你不能让它暗示对目标类型的暗示。

  

为什么从IListList<UInt16>的演员表有效,但来自IList的演员表   IList<UInt32>无效?

在我开始用我的话解释之前,请阅读Jon Skeets answer

  

您无法在C#中int[]uint[]之间直接投放,因为   语言并不相信任何转换都可用。但是,如果你   通过对象(在我的示例中为*或IList),结果取决于CLI。

CLI规范第8.7节

  

可以为每个指定有符号和无符号整数基元类型   其他;例如,int8 := uint8有效。为此目的,bool应该是。{1}}   被认为与uint8兼容,反之亦然,这使得bool:=   uint8有效,反之亦然。对于已签名的数组也是如此   和相同大小的无符号整数基元类型;例如,int32[] := uint32[]有效。