代码换肤术(一)——C#和VB


 日期:2005-6-13 16:41:00  

代码换肤术(一)——C#和VB
现在流行程序“换肤术”,就是把操作界面变个样子,程序当然还是原来的程序。代码的移植也可以称为一种“换肤术”,内容不改,但变成了另一种语言。本文介绍的是从当今最火热的C#与VB.net间移植的技巧。

按理说,这两种语言没有什么移植的必要,因为他们生成的代码可以完全通用。但是如果一个工程基本上是VB写成的,却需要少许已经存在的C#过程, 用组件并不是一种效率很高的办法。就算是学习C#或VB,学会他们之间的移植可以双倍的利用已经存在的代码(如好玩的Donkey.net就只有VB 版)。

有人比较过这两种语言,得出的结论是他们很相似。但即便是这样,VB初学者看到诸如((Button)sender).Text = “启动”;之类的语法不知道如何移植到VB,而C#初学者看到Handles Button1.Click等语法也会为移植而感到头痛。下面就看看他们最难移植的部分:

1、Option语句。VB的Option语句可以打开或关闭变量声明检查和类型转换检查。尤其是Option Strict被关闭后,VB变成弱类型语言,很多类型转换都是自动的,移植到C#中会产生无数错误。因此,如果要将带有Option Strict Off语句的VB程序移植到C#,最好先在VB中将Option Strict打开,然后把所有类型转换出错的地方变成强类型转换,然后再进行移植。

2、类型转换。VB提供了很多类型转换函数型运算符,如CInt(), CSng(), CStr()等,在C#中只要用(int) , (float), (String)即可。然而如果不是标准类型,如下面的C#语句:

((System.Button)sender).Text = “启动”;

就要使用VB的函数型运算符CType来实现。上面的代码正确的移植方法是:

CType(sender, System.Button).Text = “启动”

千万不要使用某些人推荐的,将Option Strict关闭,然后用后期绑定调用sender对象的方法,这根本不符合程序移植不能改变本质的要求。

3、修饰符和属性标签。VB和C#的修饰符是完全对等存在的,但是拼写往往不同,给移植带来了很多麻烦,尤其是表示相同意思的关键字从字面理解完全不同的时候。下面就给出了VB和C#对应的关键字:

VB
C#
VB
C#

Inherits
:
Implements
:

MustInherit
abstract
NotInheritable
sealed

Overridable
virtual
NotOverridable
sealed

MustOverride
abstract
Overrides
override

[Overloads]

Shadows
new

Shared
static
Public
public

Protected
protected
Friend
internal

Protected Friend
protected internal
Private
private

Static
用别的方法实现
ByVal

ByRef
ref
Optional

ParamArray
params
无法实现
unsafe

无法实现
fixed

可以看出,VB的关键字比较长,而且使用上也比C#更加严格。从C#向VB移植的时候,要分外注意哪些VB有而C#没有的关键字以及在C#拼写相 同,在VB中拼写不同的关键字(如MustOverride和MustInherit)。有些关键字如unsafe,如果C#使用了他们,将无法移植到 VB中。好在这些关键字在商业应用中并不常用。

属性标签在这两种语言中非常的相似,移植上应该没有任何难度,只要知道在C#中用方括号[]表示属性标签,而在VB中用的是尖括号<>。另外,如果要用名称结合传递参数,C#直接使用=号,而VB使用:=(冒号和等号)。

4、委派类型。委派类型就是安全的函数指针类型。在C#中,难以分辨是函数指针在工作还是函数本身在工作,因为他们的语法相同。当要为一个委派类型的变量复制的时候,直接等于一个函数即可,如:

public delegate void FuncType(Object e)

...

FuncType func;

func = new FuncType(this.SampleFunction1);

//调用

func(something);

//换指向另外一个函数

func = this.SampleFunction2

然而VB中,委派类型就像是一般的对象,有它的方法,与函数本身明显不同。你不能将过程的名字直接赋给一个委派类型的对象,而必须使用AddressOf运算符,下面的例子就是上文C#程序的VB版,注意那些实现不同的地方:

Public Delegate Sub FuncType(ByVal e As Object)

...

Dim func As FuncType

func = New FuncType(AddressOf Me.SampleFunc1)

‘ 调用

func.Invoke(something)

‘ 换指向另外一个函数

func = AddressOf Me.SampleFunction2

5、事件处理。这是两种语言最大的差别之一,VB传承以前版本强大的事件处理机制,许多语法都比C#更加灵活。好在无论什么情况,他们之间都是可以互相移植的。

对于事件定义,两种语言都是一个委派类型加一个事件属性,如:

[C#]

public delegate void MyEventHandler(Object sender, EventArgs e);

public event MyEventHandler MyEvent;

[Visual Basic]

Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)

Public Event MyEvent As MyEventHandler

VB还支持另外一种更加紧凑的定义方法,只有一条语句:

Public Event MyEvent(ByVal sender As Object, ByVal e As EventArgs)

移植的时候,要把参数部分分离出来,成为一个委派类型,再按照普通方法定义事件即可。

关于事件响应,C#与Delphi等语言一样,是动态绑定事件过程的,其语法类似于下:

internal MyClass myobj;

...

myobj = new MyClass();

...

myobj.MyEvent += this.myobj_MyEvent;

...

protected void myobj_MyEvent(Object sender, EventArgs e)

{

//语句

}

可以看到,C#是利用运算符连接事件过程和事件属性的。之后,还可以用-=运算符解除事件过程与事件属性的绑定。VB不支持运算符重载,但仍然支持这种动态绑定的事件过程,方法是使用AddHandler和RemoveHandler关键字。如上面黑体部分可以移植为:

AddHandler myobj.MyEvent, AddressOf Me.myobj_MyEvent

解除绑定的语法与此类似,只是关键字为RemoveHandler而已。一定不要忘记过程前面还有一个AddressOf关键字!

动态绑定的事件过程工作起来比较慢,VB支持一种更快的静态绑定事件过程。一旦为对象设置了静态的事件过程,就不能解除绑定,一般大多数情况都是如此。语法如下:

‘ 定义变量时使用WithEvents关键字

Friend WithEvents myobj As MyClass

‘ 直接书写事件过程,注意Handles的语法:

Protected Sub myobj_MyEvent(ByVal sender As Object, ByVal e As EventArgs) _

Handles myobj.MyEvent

‘ 语句

End Sub

它表示myobj_MyEvent这个过程仅仅响应myobj.MyEvent这个过程。如果一个过程要响应很多个事件,把他们列在Handles后面,用逗号隔开,如Handles Event1, Event2, ...

遇到这种情况,要看清Handles后面的所有对象和事件,将它们一一改写成动态绑定的语句:

Protected Sub XXX(...) Handles myobj1.MyEvent, myobj2.MyEvent

==>

myobj1.MyEvent += this.XXX;

myobj2.MyEvent += this.XXX;

...

protected void XXX(...){}

当事件比较多时,C#显著变得比较麻烦,幸好一个过程响应一大堆事件的情况也不太多(不过我就编写过一个过程相应8个事件,移植起来好麻烦!)。原则上说,将静态事件过程移植为动态事件过程并没有完全遵守移植的规定,但我估计他们实现的原理不会相差太多,所以也不用担心。

6、异常处理。VB支持两种形式的异常,即.net框架的异常和VB自己的错误号码。而C#只支持第一种。用到VB自己的错误号码的程序几乎无法移植到C#中,所以应该尽量使用.net框架的异常,如下面VB语句:

Try

‘ 发生错误的代码

Catch When Err.Number = 52

‘ 解决错误的代码

End Try

这段代码无法直接移植到C#中,只有用Exception对象取代Err对象获得异常信息,才能顺利移植。另外VB的When语句带给Try语句十分灵活的用法,必须用很高的技巧才能在C#中实现,这就需要具体问题具体分析了。
VB支持Exit Try语句,可以直接从Try块或Catch块跳转到Finally块。C#没有提供类似的语法,可以用以下技巧:

[Visual Basic]

Try

‘ 一些语句

Exit Try

Finally

‘ 一些语句

End Try

[C#]

try

{

//一些语句

goto __leave;

}

finally

{

//一些语句

}

__leave: //别忘了这里还有哦!

总之是利用了finally块无法跳过的特征,用goto语句模拟了Exit Try语句。

如果VB程序用的是VB特有的On Error GoTo语句实现的错误处理,问题就麻烦了。代码可能在过程中上下跳跃,无法预料语句的执行方式。这种代码理解起来就头痛,更不要说移植了。总体来说,把 所有语句统统转移到try块中,然后用catch一一处理错误。遇到要返回(Resume语句)的时候,只好Copy代码了。反正不是一件容易的事情,慢 慢改就是了。

7、模块。VB支持模块,C#不支持。但也没有关系,只要在C#中制造一个abstract类,共享所有成员,就和模块一样了。当然不能像VB一样直接访问模块中的成员,需要用到“类名.成员名”的用法。

8、接口。C#在接口方面也没有VB强大(怎么这么重要的功能也不做得好一点?),VB采用Implements语句结合接口的成员和类的实现成 员,而C#是用名称结合。因此VB就可以随便修改实现成员的访问级别和名称,而C#就不能改名称。将C#移植为VB时,最好利用VB.net编辑器直接实 现接口,比较简单。把VB移植为C#时,就必须把改过的名字都改回来,遇到名字冲突就更讨厌了(这时候我几乎不想再移植为C#了)。给一个例子:

[Visual Basic]

Public Class Class1 : Implements IMyInterface

Public Sub DoSth() Implements IMyInterface.Method1

End Sub

End Class

[C#]

public class Class1 : IMyInterface

{

public void Method1()

{

}

}

9、运算符重载。这会遇到VB头痛了,既然VB不支持运算符重载,那么就必须用子程序和函数来模拟运算符。比如建立Plus和Minus方法模 拟+和-的运算。当然还是有很多情况(比如遇上了explicit和implicit语句)就真的没有办法了,只好不移植了。运算符重载是一个很不错的功 能,它能使很多操作简单地完成,如果VB支持它,就真的是完美语言了。

好了,想必最麻烦的地方已经说完了,剩下的就是简单的Copy了。虽然有些地方还没有说清楚,但基本上阐明了两种语言的不同(一看,不同还挺多的 吧),反正也不用移植大的工程,了解这些内容主要是为了利用双倍的利用已经存在的代码,但愿本文对你有用。由于水平低劣,如有错误请各位大虾指正,小弟必 洗耳恭听。

转载于:https://www.cnblogs.com/newman78/archive/2008/08/13/1267452.html

代码换肤术——C#和VB(摘抄)相关推荐

  1. 代码换肤术(一)——C#和VB (转)

    代码换肤术(一)--C#和VB (转)[@more@] 代码换肤术(一)--C#和VB 现在流行程序"换肤术",就是把操作界面变个样子,程序当然还是原来的程序.代码的移植也可以称为 ...

  2. html css实现静态换肤,简单的JS+CSS实现网页自定义换肤

    1,实现效果 效果图 2,实现原理 主要原理是利用css变量设置颜色,用js动态修改变量,使颜色变化,兼容性如下: 兼容性 3,实现过程 实现换肤之前先要了解一下伪类选择器 :root ,还有css的 ...

  3. Qt之界面换肤【转】

    简述 实现原理 效果 新建QSS文件 编写QSS代码 加载QSS 更多参考 简述 常用的软件基本都有换肤功能,例如:QQ.360.迅雷等.换肤其实很简单,并没有想象中那么难,利用前面分享过的QSS系列 ...

  4. android 换肤框架搭建及使用 (3 完结篇)

    本系列计划3篇: Android 换肤之资源(Resources)加载(一) setContentView() / LayoutInflater源码分析(二) 换肤框架搭建(三) - 本篇 tips: ...

  5. 防仿百度图片背景色php,基于jQuery实现仿百度首页换肤背景图片切换代码_jquery...

    不多说了,先给大家展示效果图,本文支持源码下载哦,需要的朋友可以直接下载使用,代码很简单哦- html代码: css代码: *{margin:0;padding:0} a{color:#fff; ma ...

  6. 软件易容术-----换肤

    软件易容术-----换肤                                                       电子科技大学03级02班 周银辉 1, 看看成果: 换肤前 换肤后 ...

  7. 前端JavaScript(1) --Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏...

    一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...

  8. python 全栈开发,Day50(Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏)...

    一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...

  9. 一键换肤代码html,js实现简单的网页换肤效果

    中心思想:网页换肤的原理就是通过调用不同的样式表文件来实现不同的皮肤切换,并且需要将换好的皮肤计入Cookie中,这样用户已下次访问时,就可以显示用户自定义皮肤了 步骤: 1.在设计HTML代码时,用 ...

最新文章

  1. 写markdown用于Github上readme.md文件
  2. 性能优化之数据库优化
  3. Oracle11g EM界面乱码解决方法
  4. 《蓝色协议BLUE PROTOCOL》技术分享解读
  5. 沙漠上不小心挖了个洞,让这个地狱之门般的巨坑,燃烧了50年
  6. 信息学奥赛一本通 1216:红与黑 / OpenJudge NOI 2.5 1818
  7. python执行脚本时的命令行选项_Python 处理脚本的命令行参数(二):使用click
  8. 2020年5月机器视觉工作阶段性总结
  9. 属兔的人今日运势-360星座网_明日运势属兔人(12.25)
  10. 数据库课程设计报告(毕业生管理系统)
  11. python交通流预测算法_对各种交通流预测模型的简要分析
  12. ELEMENTARY: Is Even
  13. RobotStudio 项目移植问题——无法创建系统
  14. 为什么大家都在用 PDF? PDF 文档怎么修改?
  15. MetaQ安装部署文档
  16. 电子垃圾绿色回收之路怎么走?
  17. 路遇又一个流量风口,民宿长期向好的逻辑选对了吗
  18. MySQL 占用过高CPU时的优化手段
  19. lync2010企业版部署
  20. 第一个python小程序猜字游戏

热门文章

  1. 使用Oracle Wrap工具加密你的代码
  2. 如何简洁优雅地实现Kubernetes的服务暴露
  3. 网游服务端开发入门知识
  4. git:Failed to connect to github.com port 443:.....
  5. 文档服务器备份吗,本地资料和云服务器备份吗
  6. Doris之Routine Load
  7. HUE与HDFS的集成
  8. 【大数据入门二——yarn和mapreduce】
  9. weui上传组件的图片封装到formdata_自定义toast-ui富文本组件的图片黏贴上传
  10. oracle如何获取日期月份差,Oracle获取日期和月份