更新:2007 年 11 月

下表包含 C# 和本机 C++(它不使用 /clr)之间的重要比较信息。如果您是一位 C++ 程序员,此表将为您提供这两种语言的最重要差异。

说明:

C++ 和 C# 项目是从不同的项目模型派生的。有关 C++ 和 C# 项目之间差异的更多信息,请参见项目中的项管理使用解决方案资源管理器

功能

参考主题

继承:在 C++ 中,类和结构实际上是相同的,而在 C# 中,它们很不一样。C# 类可以实现任意数量的接口,但只能从一个基类继承。而且,C# 结构不支持继承,也不支持显式默认构造函数(默认情况下提供一个)。

接口

struct(C# 参考)

数组:在 C++ 中,数组只是一个指针。在 C# 中,数组是包含方法和属性的对象。例如,可通过 Length 属性查询数组的大小。C# 数组还使用索引器(验证用于访问数组的各个索引)。声明 C# 数组的语法不同于声明 C++ 数组的语法:在 C# 中,“[]”标记出现在数组类型之后,而非变量之后。

数组(C# 编程指南)

索引器(C# 编程指南)

布尔值:在 C++ 中,bool 类型实质上是一个整数。在 C# 中,不存在 bool 类型与其他类型之间的相互转换。

bool

long 类型:long 类型在 C# 中为 64 位,而在 C++ 中为 32 位。

long

传递参数:在 C++ 中,除非显式通过指针或引用传递,否则所有变量都通过值传递。在 C# 中,除非显式通过具有 refout 参数修饰符的引用传递,否则类通过引用传递,而结构通过值传递。

结构

ref(C# 参考)

out(C# 参考)

switch 语句:与 C++ 中的 switch 语句不同,C# 不支持从一个 case 标签贯穿到另一个 case 标签。

switch

委托:C# 委托大致类似于 C++ 中的函数指针,是类型安全和可靠的。

委托

基类方法:C# 支持用于调用派生类中重写基类成员的 base 关键字。而且,在 C# 中,使用 override 关键字重写虚拟或抽象方法是显式的。

base

请参见 override 的示例

方法隐藏:C++ 通过继承支持方法的隐式“隐藏”。在 C# 中,必须使用 new 修饰符来显式隐藏继承的成员。

new

预处理器指令用于条件编译。C# 中不使用头文件。

C# 预处理器指令

异常处理:C# 为无论是否引发异常都应执行的代码提供 finally 关键字。

try-finally

try-catch-finally

C# 运算符:C# 支持其他运算符,如 istypeof。它还引入了某些逻辑运算符的不同功能。

& 运算符

| 运算符

^ 运算符

is

typeof

typedef 关键字。在 C++ 中,typedef 用于为已声明的类型创建更短或更方便的名称。在 C# 中,using 指令提供此功能。

using 指令(C# 参考)

extern 关键字:在 C++ 中,extern 用于导入类型。在 C# 中,extern 用于为使用同一程序集的不同版本创建别名。

extern

static 关键字:在 C++ 中,static 既可用于声明类级实体,也可用于声明特定于某模块的类型。在 C# 中,static 仅用于声明类级实体。

static

C# 中的 Main 方法和 C++ 中的 main 函数的声明方式不同。在 C# 中,它是大写的,并且始终是 static 的。此外,在 C# 中,对处理命令行参数的支持要可靠得多。

Main() 和命令行参数(C# 编程指南)

在 C# 中,只有在 unsafe 模式下才允许使用指针。

unsafe

在 C# 中以不同的方式执行重载运算符。

C# 运算符

字符串:在 C++ 中,字符串只是字符的数组。在 C# 中,字符串是支持可靠搜索方法的对象。

字符串

String

foreach 关键字使您可以循环访问数组和集合。

foreach,in

全局:在 C# 中,不支持全局方法和全局变量。方法和变量必须包含在 classstruct 之内。

C# 程序的常规结构

#define 预处理指令:在 C++ 中, #define 指令通常用于声明常量值。在 C# 中,#define 指令不可用于此目的。在 C# 中,最好将常量定义为枚举类型(仅限整数值)或者定义为类或结构的静态成员。如果具有多个像这样的常量,可以考虑创建一个单独的“Constants”类来保存这些常量。

static(C# 参考)

const(C# 参考)

enum(C# 参考)

导入类型:在 C++ 中,多个模块公用的类型放置在头文件中。在 C# 中,可通过元数据获取此信息。

using

元数据概述

C# 中的局部变量在初始化前不能使用。

方法(C# 编程指南)

内存管理:C++ 语言不提供垃圾回收功能;在进程终止前,未显式释放的内存仍保持已分配的状态。C# 语言提供垃圾回收功能。

垃圾回收

析构函数:C# 具有用于确定地释放非托管资源的不同语法。

析构函数

using 语句(C# 参考)

构造函数:与 C++ 类似,如果在 C# 中不提供类构造函数,则为您自动生成一个默认构造函数。该默认构造函数将所有字段初始化为它们的默认值。

实例构造函数

默认值表

C# 不支持位域。

C++ 位字段

C# 的输入/输出服务和格式设置依赖于 .NET Framework 的运行库。

C# 语言教程

格式化数值结果表

在 C# 中,方法参数不能有默认值。如果要获得同样的效果,请使用方法重载。

编译器错误 CS0241

在 C# 中,以类似于 C++ 模板的方式提供用于类型参数化的泛型类型和泛型方法。不过,二者有明显区别。例如,在 C# 中,泛型类型信息在运行时保留。

C# 中的泛型

as 关键字与标准强制转换类似,不同之处在于:如果转换失败,则返回值为 null,而不是引发异常。这与使用 C++ 中的 static_cast(与 dynamic_cast 不同,它不执行运行时检查,因此失败时不引发异常)相似。

as(C# 参考)

有关 C# 和其他编程语言中的关键字之间的比较的更多信息,请参见对等语言。有关 C# 应用程序的常规结构的信息,请参见 C# 程序的通用结构(C# 编程指南)

请参见

概念

项目中的项管理
使用解决方案资源管理器