C# VS C++(一)

C/C++出身的程序员,学习C#免不了要进行诸多对比。当然这不是坏事。以下就是我学习C#过程中遇到的不同之处,井蛙之见。

1、 关于变量的命名:我所选的“教科书”上给出了以下的建议,据说是为了与公共语言规范 (Common Language Specification, CLS)的相容性:

  • 不要使用下划线(受VC的影响,偶的变量名中经常出现下划线,确实不方便)。
  • 不要创建只是大小写区别的标识符。
  • 使用小写字母作为变量名的首字母。
  • 包含多个单词的标识符中,第二个单词开始,每个单词都采取首字母大写的形式(camelCase记号法)。
  • 不要使用匈牙利记号法(Hungarian notation)(又是VC的遗毒!)。

2、 未赋值的局部变量:C#中不允许使用未赋值的变量。一个变量必须赋值才能使用,否则无法编译。就是所谓的明确赋值规则(Definite Assignment Rule)

3、 C/C++中可以隐式转换的,在C#中不一定行,例如:

   1: float var;
   2: var = 2.4;

这样的语句在C#中是不能编译的,必须改为

   1: float var;
   2: var = 2.4F;

4、 C/C++中,不可以对浮点数使用%操作符,但在C#中可以。

5、 C#不支持全局方法,即所有的方法必须在一个类的内部,否则代码无法编译。

6、 C++接受了C中在缺少数据类型情况下默认为int的传统(尽管C++反对这样做),但是在C#中这是不被允许的。例如:如果你的方法不返回任何值,那么必须使用 void关键字。下面的代码是无法编译的:

   1: showResult( int answer )
   2: {
   3:     //…
   4: }

7、 注意C#中的短路求值(short circuiting),实际上在C/C++中也应该注意这一点。

8、 C/C++中的if语句中表达式可以是整数,编译器能自动将整数值转换为true,或是false,但在C#中必须是布尔表达式。假如你在if语句中不慎写了一个赋值表达式,而不是执行一个相等性测试,C#编译器也能识别你的错误。

9、 C#存在不准贯穿(fall through)的规则,必须为switch语句中的每个case(包括default case)都提供一个break语句。减少自由度,来增加代码的安全。

10、 C#可以有选择地启用溢出检查功能。可以在工程中全局设置,也可以随时使用checked和unchecked关键字来选择性地打开和关闭程序的一个特定部分的溢出检查。这些关键字将覆盖编译器选项。

11、异常抛出时,会改变程序的执行流程。就意味着不能保证当一个语句结束之后,其后面的一个语句肯定会运行,因为前一个语句可能抛出一个异常。C#提供了关键字finally,Finally块要紧接在try块之后,或者紧接在try块之后的最后一个catch处理程序之后,这样finally块就总会执行。

12、 C#中public或者private关键字之后不要添加冒号。必须为每个声明重复这些关键字。private是默认的,可以省略,但不推荐这样做。

13、 C#中的类字段自动初始化为0或者null(视类型而定)。当然最好显式初始化。

14、 C#支持部分类,一个类拆分到多个文件中之后,在每个文件中使用partial关键字来定义类的不同部分。

15、 .NET Framework推荐了以下字段和方法命名约定,是以类成员的可访问性为出发点来考虑的:

  • public性质的标识符应该以大写字母开头。
  • 非public性质的标识符(其中包括局部变量)应该以小写字母开头。

当然也有例外,就是类名应该大写字母开头,所以构造函数(即使是private的)也应该以大写字母开头。

16、 C#中可以定义static类,其中只能包含static成员。不能包含任何实例数据或方法。

17、 C#中“引用”和C++中的“引用”差不多(但写法不同),只是在C++中,除了“引用”,还有一个更强大的东东——“指针”。C#中没有“指针”,除了“引用类型”(“间接类型”),就是“值类型”(“直接类型”)。

18、 C#中向一个ref参数传递一个实参时,实参也必须附加ref关键字作为前缀。

19、 C#中的out的关键可以实现方法本身对参数的初始化。out和ref非常相似,可以使参数成为实参的一个别名。

20、 C#中要明确这一点,值类型是存在于堆栈(stack)中,而引用类型的实际内容是存在于堆(heap)中,所以对值类型变量的装箱(Boxing)实际上是在堆中创建了它的一个副本。

21、 访问已经装箱的值,必须进行一次强制类型转换(cast),这就是拆箱(Unboxing)

22、 C#中的枚举和C/C++中的枚举定义时差不多(只是定义后可以不加分号),但在使用上有不同。所有枚举直接量名称都要使用它们的枚举类型来限制范围,这样就允许不同的枚举类型包含同名的直接量,这一点要优于C++。C#中的枚举还可以选择基础类型,以节省内存。

23、 C#中的结构和类语法上相似,但两者有些重要的差别:

  • 不能为结构声明一个自己的默认构造函数(无参数构造函数),因为编译器将始终生成一个默认的构造函数。这一点也是和C++中的结构的区别。结构的默认构造函数和类一样,总是将字段设为0、false或者null。你可以为结构提供自己的非默认构造函数,用以初始化为其它的值。但是如果你在自己的构造函数中没有初始化一个字段,编译器将不再帮你初始化它。这意味着必须在结构的所有构造函数中显式地初始化所有字段,否则就会有编译器错误(还不错,在编译时会报错)。
  • 在一个类中,可以在声明的同时初始化实例字段,但在struct中不能这样做。C++中的类声明同时也是不能初始化成员变量的,当然有例外,如果一个静态数据成员既是const类型又是整型,那么声明就可以初始化,但是应该要类的定义文件中对其进行定义。

24、 C#中结构的初始化,要注意,因为是值类型,所以如果不用new的话,编译器不会为你做结构字段的初始化工作。

25、 C#中的数组声明和C/C++中的不同,数组的大小不是声明的一部分。实际上C#中的数组是new出来的。

26、 C#中的数组是new出来的,所以其初始化方式和C/C++也不相同。

   1: int[] dogs = new int[4] { 1, 2, 3, 4 };

27、 C#提供了foreach语句来遍历一个数组的所有元素。

28、 C#中将C++中原来模板中才有的东东,吸收了进来,数组,集合,队列……,不多说了。

29、C#中的参数数组和C/C++中的数组作参数有不同,C/C++数组做参数一般要传入数组的大小,而C#中由于数组已经是一个对象,所以可以不用传入数组长度,相当于C/C++中的变长参数列表。C#中为了省去自己编写额外的代码来填充传入的数组,提供了params关键字,要注意的是:

  • 只能在一维数组上使用使用params关键字。
  • 不能重载一个只基于params关键字的方法。params关键字不构成方法的签名的一部分。
  • 不允许ref或out parmas数组。
  • params数组必须是方法的最后一个参数(也就是说,每个方法只能有一个params数组参数)。
  • 编译器会检查并拒绝任何可能有歧义的重载。如下,如果传递两个参数,将无法分辨具体应该调用哪一个:
       1: // 编译错误
       2: public static int Min( params int[] paramList )
       3: {
       4:     //…
       5: }
       6:
       7: public static int Min( int first, params int[] paramList )
       8: {
       9:     //…
      10: }
  • 非params方法总是优先于一个params方法。如下,假如传递两个参数,那么调用的肯定是Min方法的第一个版本。假如传递其他任意数量的int参数,则调用第二个版本(其中包括调用方法时无参数的情况):
       1: public static int Min(int leftHandSide, int rightHandSide)
       2: {
       3:     //…
       4: }
       5:
       6: public static int Min(params int[] paramList)
       7: {
       8:     //…
       9: }
  • 声明不带params数组参数的方法,可以避免编译器创建和填充太多的数组。

30、 C#中也可以继承和派生。但和C++不同,一个类最多只允许从一个类中派生;不允许从两个或者更多的类中派生。而且,C#中继承总是隐式为public,不可以显式指定。(C++的多重和公有、私有、保护继承总是把人搞晕,这下清静了。)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值