浏览模式: 标准 | 列表
1月
03

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对象上做判断时,一定要注意这个问题,否则很容易掉进这个陷阱中去。

 

前天,微软知名 MVP,MSDN 特邀讲师衣明志先生在MSDN上做了一次关于 Hprose for .NET 的 Webcast,现在该课程的录像和课件已经放出来了,希望了解 Hprose 或者分布式开发的同志们有时间的话,不妨看看这个视频。

该视频的MSDN Webcast在线点播地址为:MSDN Webcast – 在ASP.NET 4中使用Hprose开发分布式应用

本站下载地址:教程 视频

» 阅读全文

在 .NET Framework 3.5 beta 时,微软曾引入了一个新的包 System.Numerics,其中包含了大整数类,不过可惜在后来的接近发布时,这个包又移除了。现在 .NET Framework 4.0 又重新将它请了回来。而且这次的正式版本中不会再次移除了。这对 .NET 开发者算是一个好事,但如果只有使用 .NET Framework 4.0 的用户才能享受到这个包,还是不太完美,毕竟现在大多数 .NET 开发还停留在 2.0 或 3.5 的阶段。

我们最近新推出的 PHPRPC 的商业版 Hprose 最显著的一个特点就是多语言互通,让各个版本的 .NET 程序之间无障碍互通更是小菜一碟。但如果只有 .NET 4.0 中有 BigInteger,就无法将其传给 .NET 的早期版本,怎么谈得上无障碍互通呢?为了解决这个问题,我们将 System.Numerics 移植到了 .NET 4.0 之前的所有版本上,现在不但 .NET Framework 1.0、1.1、2.0、3.5 可以使用 System.Numerics 的所有类了,连 .NET Compact Framework 1.0、2.0、3.5,SilverLight 2.0、3.0、4.0,Mono 1.0、Mono 2.0 也都可以使用了。

虽然我们的商业版Hprose本身不是免费的,但是这个移植的 System.Numerics.dll 我们是免费开放的。你不需要支付任何费用,就可以将它用于您的任何程序当中。是不是很爽?哈哈,那还等什么,还不赶快下载试试。

下载地址:System.Numerics.dll

» 阅读全文

下面是对在 .NET Framework 3.5 中对 PHP、Binary、SOAP、XML、JSON、Hessian 和 Burlap 序列化/反序列化的效率对比,其中 PHP 序列化来自最新版本的 PHPRPC 3.0.1 for .NET,Hessian 和 Burlap 序列化来自Hessian C# 的最新版 1.3.3,其它的序列化都是采用 .NET Framework 3.5 中内置的功能。

测试程序可从此处下载:test.zip

下面是测试程序的运行结果图:

大小: 30 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 30.4 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 30.33 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 29.72 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 31.22 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 29.51 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 34.28 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 34.41 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 36.12 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 39.11 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 35.34 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 34.93 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图
 

从上面的运行结果来看 PHP 序列化和反序列化:

对于基本类型的效率跟 Hessian 不相上下,远远超过其它序列化方式,甚至比 .NET 的 Binary 序列化和反序列化都要快好几倍。但是 Burlap 不支持浮点数的无穷大表示。

对于字节数组来说,速度是 Binary 序列化的 2 倍,是 Hessian 的 10 倍,是 Burlap 的 25 倍,是 SOAP 的 36 倍,是 JSON 的 1000 多倍!

对于数组来说,具有相同元素的数组,比 Binary 序列化要差一些,但是远远超过 SOAP、XML、JSON、Hessian 和 Burlap。具有不同元素的数组,跟 Binary、Hessian 序列化效率接近,比 XML、JSON、Burlap 稍快,远远超过 SOAP。

对于 Hashtable 来说,效率也是超过 .NET Binary、Hessian 和 Burlap 序列化。比 SOAP 快近 10 倍,比 JSON 快了近 100 倍!而 XML 不支持。

对于 ArrayList 和自定义类型来说,效率不如 .NET Binary 序列化,但是仍然远远超过 SOAP、Hessian 和 Burlap,而 XML 和 JSON 则根本不支持。

而在空间占用上,其效率也超过了 Binary、SOAP、XML、Burlap,在基本类型上与 JSON、Hessian 不相上下,对于数组、Hashtable 则远远超过 JSON。

所以,从上面的对比来看,PHPRPC 中所使用的 PHP 序列化是一种非常高效的数据表示方式,远远超过 SOAP、XML、JSON、Burlap 等序列化方式。其效率跟 .NET Binary、Hessian 序列化的效率可以算是不相上下,在综合水平上甚至超越了 .NET Binary、Hessian 序列化。另外在跨语言跨平台方面,PHPRPC 所使用的 PHP 序列化方式则比 .NET Binary 序列化要好的多,而 PHPRPC 本身又在稳定性、易用性、安全性、功能性和脚本语言的支持上又比 Hessian 好很多,通过这些数据我想更加可以说明 PHPRPC 的优秀了。

» 阅读全文

这个版本的更新是对反序列化效率的优化,优化后的效率提升有 100 倍之多。

在优化过程中发现最耗时的操作居然是 try/catch 操作。而且差别不是一点点,使用 try/catch 所耗费的时间是不是用 try/catch 所耗费时间的 100 倍还多,以至于我在效率对比测试时发现,PHP 反序列化居然比 SOAP 还慢,经过优化后,将不必要的 try/catch 替换为 if/else 后,反序列化的效率远远的超过了 SOAP,甚至接近或超过 .NET 二进制序列化的速度。

新版本下载地址不变,仍然是:http://www.phprpc.org/download/

» 阅读全文