Jim's blog -- Focus On ERP/.NET/BI

Dynamics AX ERP, .NET, Business Intelligence

导航

软件设计之道:平衡之术

.NET程序员是幸福的,基本上是被MS给宠坏了,老板们是乐坏了,可是身为程序员却高兴不起来(个中原因自己体会吧)。借着MS的开源春风,让我们看看MS到底是怎么宠坏我们这些可爱的.NET程序员的。在MS设计产品时遵循哪些规则,又是怎么解决一些棘手的问题的。让我们看看微软的完全开源的IronPython,看看MS是怎么耍宝的。

微软现在已经是Python Software Foundation (PSF)的成员(跟当初微软加入Java队伍好相似呵),那理所当然IronPython得和CPython兼容以照顾原有的Pythoner们,但IronPython又是建立在.NET FrameWork上的,同样得很好的照顾到大量.NET程序员。这两者之间肯定会有冲突,微软是如何在这两大群体间保持平衡的呢?让我们看几个简单的例子来体会IronPyhon的设计之美。

一个看起来很简单的字符串处理问题:

>>> s = "python and .networking together"
>>> s.upper()

Python中使用upper函数去得到大写的字符串,但是.NET中我们使用String.ToUpper()方法。如果是你,这时你会怎么做,也许你会想到.NET扩展方法从而这样处理:

>>> s = "python and .networking together"
>>> s.upper()
'PYTHON AND .NET WORKING TOGETHER'
>>> s.ToUpper()
'PYTHON AND .NET WORKING TOGETHER'

可是这样的话原来的那些Pythoner就会吼了,他们要求兼容性,CPython可不支持ToUpper()方法。那再想想,有什么方法能解决这个问题呢,真是众口难调啊。刚才想到扩展方法,恩,我们可以这样处理:

>>> s="python and .networking together"
>>> s.upper()
'PYTHON AND .NETWORKING TOGETHER'
>>> s.ToUpper()
Traceback (most recent call last):
  File 
"<stdin>", line 1in <module>
AttributeError: 
'str' object has no attribute 'ToUpper'
>>> import clr
>>> s.ToUpper()
'PYTHON AND .NETWORKING TOGETHER'
>>>

怎么样,现在大家都满意了吧。类似的我们可以解决IronRuby中的to_upper;VB中的toupper,ToUpper,TOUPPER。

再举个关于异常处理的例子:
>>> import System
>>> System.Math.DivRem(5,2)
(
21)
>>> System.Math.DivRem(5,0)
Traceback (most recent call last):
  File 
"<stdin>", line 1in <module>
ZeroDivisionError: 试图除以零。
看到问题了没?细心的.NET程序员会叫道:我在C#里不是会抛出DivideByZeroException异常吗?怎么到了IronPython里同样的错误却抛出了ZeroDivisionError异常呢。恩,貌似是个问题,让我们看看IronPython是怎么处理这个问题的:
>>> try:
     System.Math.DivRem(
5,0)
 
except ZeroDivisionError,e:
     
print e,type(e)

试图除以零。 
<type 'exceptions.ZeroDivisionError'>
Pythoner确实捕获到了想要的异常,这样对于原来的Pythoner确实照顾得很好。对于.NET程序员呢,能不能捕获到DivideByZeroException异常呢,做个实验吧:
>>> try:
     System.Math.DivRem(
5,0)
 
except System.DivideByZeroException,e:
     
print e,type(e)

System.DivideByZeroException: 试图除以零。
   在 _stub_$
17##16(Closure , CallSite , CodeContext , Object , Int32 , Int32 )
   在 _stub_MatchCaller(Object , CallSite , Object[] )
   在 Microsoft.Scripting.Actions.CallSite`
1.UpdateAndExecute(Object[] args)
   在 Microsoft.Scripting.Actions.UpdateDelegates.Update4[T,T0,T1,T2,T3,TRet](Ca
llSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   在 Initialize$
27##26(Closure , CodeContext ) <type 'DivideByZeroException'>
同样很好很强大,也捕获到了.NET DivideByZeroException异常。有人要问了:这个异常到底是什么类型呢,再试验下:
>>> import System
>>> try:
     System.Math.DivRem(
5,0)
 
except System.Exception, e:
     
print type(e)

<type 'DivideByZeroException'>
>>>
还是.NET中的DivideByZeroException异常。

posted on 2008-07-31 09:53  季方亮  阅读(3622)  评论(10编辑  收藏  举报