C# 中 is 和数组的问题

在C#中,我们可以很方便的在object对象上使用is运算符来快速的判断对象的类型,is运算符还具有在子类对象上判断是否属于某个父类或者接口的能力,与之等价的判断是,使用GetType方法获得类型后,使用父类或接口上的IsAssignableFrom方法来判断。后者速度比使用 is 运算符要慢很多。所以通常我们在存在对象和已知要判断的类型时优先使用is运算符。

但是is运算符在判断数组类型时却有一个bug,当然这个bug也许是设计问题,但是它确实可能跟我们期望的行为不一致。

这个bug可以这样描述,当一个整数数组对象(byte[], sbyte[], short[], ushort[], int[], uint[], long[], unlong[]这八种)被赋值给一个object对象时,在这个object对象上使用is方法判断时,在等位长整数类型上判断的结果总为True,与类型是否有符号无关。例如:

C#代码
 
  1. int[] a = new int[] { -3, -2, -1, 0, 1, 2, 3 };  
  2. Console.WriteLine(a is int[]);  
  3. Console.WriteLine(a is uint[]);  
  4. object o = a;  
  5. Console.WriteLine(o is int[]);  
  6. Console.WriteLine(o is uint[]);  
的输出结果为:

True
False
True
True

前三个输出是我们期望的,但是最后一个输出的True却是出乎意料的。

这里如果把 int[] a 换成 uint[] a 也是一样,例如:

C#代码
 
  1. uint[] a2 = new uint[] { 0, 1, 2, 3 };  
  2. Console.WriteLine(a2 is int[]);  
  3. Console.WriteLine(a2 is uint[]);  
  4. o = a2;  
  5. Console.WriteLine(o is int[]);  
  6. Console.WriteLine(o is uint[]);  
的输出结果是:

False
True
True
True

第三个输出结果True是我们意料之外的。

同样byte[]和sbyte[]也存在这种关系,short[]和ushort[],long[]和ulong[]之间同样也存在这种关系。

所以使用is在这几种数组的object对象上做判断时,一定要注意这个问题,否则很容易掉进这个陷阱中去。

标签: C#, is, array, 数组, .NET

« 上一篇 | 下一篇 »

只显示10条记录相关文章

发表评论

评论 (必须):