作者:西瓜凉皮大夏天 | 来源:互联网 | 2023-05-17 09:04
在网上经常能看到一些评论和比较C#、VB.net优劣的文章。其中绝大多数都认为:VB.net就没有它存在的必要,VB.net迟早要被C#取代。确实,计算机语言不是很重要
在网上经常能看到 一些评论和比较 C# 、 VB.net 优劣的文章。其中绝大多数都认为: VB.net 就没有它存在的必要, VB.net 迟早要被 C# 取代。 确实,计算机语言不是很重要的,也许讨论它有点无聊。所以还希望那些 “ 心中无剑 ” 、 “ 架构、思想至尚 ” 的高手们口下留情。 关于 VB.net 与 C# 在功能、能力、面向对象的特性上,实在是难分伯仲。这个已是不争的事实。尤其是 VS.net2005 中,这两种语言已经达到了惊人地相似! 下面就通过三个大方面对这这两种语言进行比较: 一、语言的人性化区别 C# 像傻男人, VB.net 像聪明贤惠的女人 从代码的风格就可以看出。 例 1. 声明变量时: C#: int iTest ; // 很直接的语气 , 类似于 : 擦汗!拿毛巾 VB.net Dim iTest As Integer ‘ 很委婉的语气 , 类似于 : 小王 , 给我拿条毛巾 , 我用它擦汗 ~ 实现完全相同的功能,但有着很明显的区别。哪个更人性化、更易懂呢? 例 2. 语言的关键字上: C# 关键字: using 、 this 、 void 、 base 、 abstract 、 sealed 、 virtual 、 switch 、 internal 、 static 相应的 VB.net 关键字: Imports 、 Me 、 Sub 、 MyBase 、 MustInherit 、 NotOverridable 、 MustOverride 、 Select 、 Friend 、 Shared 比较一下, C# 的关键字比较冰冷,是具有一定 “ 机器味道 ” 的语言。 而 VB.net 的关键字,都是 “ 人的行为 ” , “ 人的称谓 ” 。 相信 VB.net 的语法更具亲和力,更易于帮助我们理解面向对象的特性。 二、语言的先进性的对比 现在,计算机软件工程越来越庞大,已经远远不是 10 年前的几十 KB 大小的级别了。这就对语言的可扩展性、可辅助性提出了更高的要求。 “ 面向对象 ” 便是这个需求的一个产物。 从现有的语言来看,具有 “ 标识符 ” 的标识性语言具备更高的容错性、可调试性、可扩展性。比如 HTML 、 XML 。尤其是 XML 已经成为了下一代语言的模型。 为什么像 HTML 、 XML 这种具有 “ 开口 ” 和 “ 封口 ” 的语言 有更高的容错性、可调试性呢?这要取决于它的 “ 吝啬 ” 性。 “ 开口 ” 和 “ 封口 ” 可以把故障的范围最小化,使出现问题的部分尽量不影响其它部分。比如说:在 HTML 的 中,少写一个 多写一个 均不会对表格中其它行造成太大的影响。
与 这种 “ 吝啬 ” 的语法相反的是 “ 贪婪 ” 性的语法。什么是 “ 贪婪 ” 性呢?这个问题也不太好解释。不过,这种特性与正则表达式的解析十分十分地一致。 “ 吝啬性 ” 的正则表达式 用做 精确匹配 Group 时有着较高的性能,而 “ 贪婪性 ” 的正则表达式用于判断 IsMatch 时有着较高的性能。 像 C 类的所有封口均使用大括号的语言,就属于这种 “ 贪婪性 ” 性的语言。过多相同的封口使得代码更加地难于控制。 许多人抱怨微软,为什么不给 C# 加上动态编译、加上自动完成 …… ,实际上,微软何尝不想加啊,但由于 C# 的语法特性,是根本无法实现的。下面就用实例来说明为什么 C# 无法实现动态编译: 看下面的 C# 代码段,代码中的大括号是不平衡的: class A { class B { class C { int F1() { return 1; } int F2() { return 2; } } } 假如现在已经有了 C# 的动态编译器,现在 要求编译器指明 到底是哪里丢失了大括号! 这时,编译器就糊涂了:因为 不论是把大括号加在 F1 的末尾 还是加在 class A 的末尾 都是行得通的,虽然这两种情况的意义是完全不同的,即:不能判断 F1 到底是 Class C 的方法,还是 Class B 的方法。那么连带下一步,在代码的其它部分 就更无法判断 调用 F1 的代码的合理性了。 这里只是举了一个简单的例子,实际的情况比这个更复杂。我们可以看到,在 C 语言的代码没有完全正确地书写之前,它的结构是有可能极度混乱、多意性的,在这种极度混乱的环境下 是无法判断故障之所在、无法正确识别对象的结构的。自然,这样的动态编译器也就成了 “ 累赘 ” 。 相比之下,同样的内容 看看 VB 语法: Class A Class B Class C Function X1() As Integer Return 1 End Function End Class Function X2() As Integer Return 2 End Function End Class End Class 无论你删除 End Class 还是删除 End function ,故障范围都不会扩大,定位就可以做到精准。 检错如此,自动完成代码也是如此。在 C# 环境下,由于代码结构可能存在着 “ 多意性 ” ,所以 IDE 有可能无法决定做处理的确切位置。 当然, C 类的代码并不是没有优点,其优点主要有二: 1. 节省代码所占的磁盘和内存空间 2. 使编译器的体积能够做得更小(最终还是为了节省磁盘空间) 只有在 内存和磁盘空间非常珍贵的过去的年代里, C 类语言代码才能够更具优势。 然而在内存和磁盘如此丰富的今天,这种优势已经成了劣势。 借助于这种具有确定的 “ 开口 ” 与 “ 封口 ” 的特性,相信 VB.net 会走得更远。 三、语言的灵活性、适应性的对比 C# 的代码,可以 “ 随便书写 ” :在一行里可以写多条语句,一条语句可以分成多行来写。这使得它的代码有可能更加地 “ 松散 ” 。虽然 C# 允许您把代码写得非常地松散,不过在实际的使用中,几乎所有的使用者都默默地走向了 VB 的代码风格(一行一条语句)。最后,它的分号成了累赘。 虽然 C# 的代码更加地自由,不过 C# 的思想比起 VB.net 起来却是更加地死板。 在这方面,我觉得把 C# 比做手动档汽车、把 VB.net 比做自动档汽车是比较合适的。自动档汽车也可以用手动档的方式驾驶。 C# 的思想、思路在 VB.net 中均可实现,而 VB.net 的思想(自动档)却经常无法在 C# 上实现。下面举例说明: 例一:事件模型 在 C# 中,事件模型是固定的,构造一个事件模型通常需要下面的思路: 建立事件代理结构、声明事件、建立事件处理方法、添加事件句柄、判断事件代理是否挂到上实例、通过代理方法引发事件。 在 VB.net 中,即可以按照 C# 所用的模式建立事件,也可以用 VB.net 自身所带的 RaiseEvent 方法实现。虽然他们编译后的结构几乎是一样的,但毕竟 VB.net 让我们有了更多的选择,何乐而不为呢?下面就看看 VB.net 引发事件的两种方法示例: 方法一:用 RaiseEvent. 这是一种非常快捷、代码思路非常清晰的一种方法: Class EventClass Public Event E1(sender as Object,e as XXXEventHandler) Sub XXXX() RaiseEvent E1(Me,new XXXEventHandler(…) End Sub End Class 方法二:用 C# 的的思路 Public Delegate Sub xxxHandler(ByVal sender As Object, ByVal e As EventArgs) Public Class A Public Event XXX As xxxHandler Public Overridable Sub OnXXXEvent(ByVal sender As Object, ByVal e As EventArgs) If XXXEvent IsNot Nothing Then XXXEvent.Invoke(sender, e) End If End Sub Sub X() OnXXXEvent(Me, New EventArgs) End Sub End Class “ 用尽量少的代码 做出更多的事情 ” 是每个人程序员的最爱! 很显然, VB.net 在这方面占尽了优势。 例二:可选参数结构 如下代码展示了 VB 特有的结构:可选参数 Public Sub XXX(P1 As Integer,Optional P2 As String,Optional P3 As String) ‘… End Sub 这样的结构在 C# 中是无法实现的,但可以通过 “ 重载 ” 的方式实现相同的效果: void XXX(int P1){} void XXX(int P1,string P2){} void XXX(int P1,string P2,string P3{} 当然,用 VB.net 也可以用重载方式写出一模一样的结构。 例三:事件代理的挂接 C# 中:只有一种方法: XXX.XXX += new XXX(…); VB.net 中:即可以效仿 C# 的方法: AddHandler(XXX.xxx,AddressOf XXX) 也可以把过程显示地指定给某个事件: Sub(…) Handles XXX.XXX 利用上面的第二种方法的特性,可以实现在 VB.net 代码编辑页中 简单地通过下拉框 来精确地定位某个对象的特定事件的处理过程。 遗憾的是,这种方便的特性在 C# 中是无法实现的。因为 C# 的语法 :XXX.XXX += 的后面可以是任何方法返回的具有相同签名的实例。比如 通过属性、方法,甚至是随机判断后返回的。 这种 “ 过份的自由 ” 使得 C# 编译器在运行代码前不能准确地确定该对象事件的处理部位。 类似的例子太多了,举不胜举。 总之, VB.net 给了我们更大的活动空间,它允许我们在 “ 更快的速度 ” 和 “ 更严格性能要求 ” 之间自由选择。 四、代码书写上的比较 一、变量的命名的区别 C# 是区分变量的大小写的,这一点着实让人摸不着门。也许这仅仅是为了效仿 Java? 在公共语言规范中 (CLS) ,明确规定 “ 变量不区分大小写 ” 的,真是难为了 C# 编译器,还要把 “ 重名 ” 的变量重新命名。 相比之下, VB.net 更加符合 CLS ,而且因为不区分大小写,编辑器就更轻松地实现了 “ 自动更正 ” 功能。 C# 绝对是 “ 嫁错了人 ” 。 C 要区分大小写,其原因有二:一是为了能使用更多的变量资源,二是为了节省编译器的开销(性能和体积上都节省)。 如今, .net 环境允许我们使用多达 1024 个长度的变量名,而且已完全面向对象化,相同的变量可以同时出现在任何 object 中,所以可用的变量资源数量 理论上已经达到了无穷多个! 在这样的条件下, “ 区分大小写 ” 使代码在 可读性、可调试性、可辅助性上都造成了不小的负面影响!它已经成为了语言发展的障碍! 二、代码的书写 几乎绝大多数的 C# 程序员都觉得他们在代码的书写上有着无与伦比的优越性,因为 C# 代码看上去是如此的简洁。 是的,如果我们仅使用记事本来开发 .net 应用程序,我相信像 VB 、 Delphi 早就灭绝了。 但更糟糕的是:如果我们仅能使用记事本写代码,那么程序员也早就集体自杀了。 说多少也不会有人相信,尤其是 C# 程序员不会相信 在代码书写方面 他们会完败于 VB.net 程序员。 我们完全可以用 “ 键盘钩子 ” 做个小程序来检测、验证一下到底是哪种代码更浪费键盘、书写起来更吃力。(这个程序我已经写好,有兴趣的可以到 http://img.pcpop.com/upimg2/2005/5/15/491525800.jpg 来下载。注意:必须使用网络快车下载,下载后把文件更改为 exe 的即可直接运行。这个序使用 VB.net + Framework1.0 编写,必要的时候 需要你安装 .net 框架。) 测试结果很明显: VB.net 代码需要按键的次数更少、书写更为容易。原因是 IDE 在其中起到了极大的作用! VB.net 不必像 C# 那样不停地用 Ctrl+shift+B 来编译检错;不必不停地按下 Shift 键来输入星罗棋布的符号;不必不停地使用 Ctrl+] 徘徊于大括号之间;更不必手动输入众多的 “ 关闭符 ” 。 (试一试:输入 If A=B [ 回车 ] ,这时 Then 和 End IF 马上就都给你准备好了) ( 再试一试:在一个刚刚建立的新 Class 中,输入 Inherits 后 回车,所有需要实现的方法都给你准备好了 ) 究其本质,是由于 VB.net 的语言起到了决定性的作用。 正是因为我们已经告诉了编辑器 “ 这是一个 ReadOnly Property” ,所以编辑器会给我们自动提供了 Get 结构代码; 正是因为我们已经告诉了编辑器 “ 这是一个 WithEvents 的对象 ” ,所以编辑器会在对象事件选择列表里加入它; 正是因为我们已经告诉了编辑器 “ 这是一个 Event” ,所以当我们要 RaiseEvent 时,它会准确地出现在列表中; 正是因为我们已经告诉了编辑器 “ 这是一个 Function” ,所以当我们写上调用方法后,它会自动地在后面加上括号; …… 反观 C# ,由于代码过度地萎缩,许多事情还需要通过分析整段代码的结构来决定它的属性,导致这些 “ 智能的操作 ” 无法在 C# 上实现。
但这些动词并不能表明VB.net和C#之间具有什么差距!!!!
推荐阅读
本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ...
[详细]
蜡笔小新 2023-12-13 18:29:11
本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ...
[详细]
蜡笔小新 2023-12-13 14:24:45
本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ...
[详细]
蜡笔小新 2023-12-13 10:58:55
The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ...
[详细]
蜡笔小新 2023-12-14 19:58:05
本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ...
[详细]
蜡笔小新 2023-12-14 16:44:09
最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ...
[详细]
蜡笔小新 2023-12-14 14:25:50
本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ...
[详细]
蜡笔小新 2023-12-13 16:37:19
本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ...
[详细]
蜡笔小新 2023-12-12 12:09:33
本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ...
[详细]
蜡笔小新 2023-12-10 14:33:46
Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ...
[详细]
蜡笔小新 2023-12-10 12:41:53
本文详细介绍了Unity3D引擎的体系结构和功能。Unity3D是一个屡获殊荣的工具,用于创建交互式3D应用程序。它由游戏引擎和编辑器组成,支持C#、Boo和JavaScript脚本编程。该引擎涵盖了声音、图形、物理和网络功能等主题。Unity编辑器具有多语言脚本编辑器和预制装配系统等特点。本文还介绍了Unity的许可证情况。Unity基本功能有限的免费,适用于PC、MAC和Web开发。其他平台或完整的功能集需要购买许可证。 ...
[详细]
蜡笔小新 2023-12-10 11:01:31
当界面需要在程序运行中不断更新数据时,使用多线程可以解决界面卡死的问题。一个主线程创建界面,使用一个子线程执行程序并更新主界面,可以避免卡死现象。本文分享了一个例子,供大家参考。 ...
[详细]
蜡笔小新 2023-12-10 10:37:32
本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。 ...
[详细]
蜡笔小新 2023-12-09 22:17:43
本文介绍了在实现了System.Collections.Generic.IDictionary接口的泛型字典类中如何使用foreach循环来枚举字典中的键值对。同时还讨论了非泛型字典类和泛型字典类在foreach循环中使用的不同类型,以及使用KeyValuePair类型在foreach循环中枚举泛型字典类的优势。阅读本文可以帮助您更好地理解泛型字典类的使用和性能优化。 ...
[详细]
蜡笔小新 2023-12-09 09:22:34
loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ...
[详细]
蜡笔小新 2023-10-17 21:26:42