小马的天空
我为软狂

导航

 

Visual Studio:针对 Java 开发人员的 C# 编程语言
发布日期: 7/23/2004 | 更新日期: 7/23/2004
本文讨论 Java 和 C# 之间的异同点,目的在于当迁移到 .NET 时,让 Java 开发人员掌握所涉及的一些知识。Java 和 C# 之间的主要相似点是:

? Java 和 C# 都源于 C++,并且共有 C++ 的一些特征。
 
? 两种语言都需要编译成中间代码,而不是直接编译成纯机器码。Java 编译成 Java 虚拟机 (Java Virtual Machine, JVM) 字节码,而 C# 则编译成公共中间语言 (Common Intermediate Language, CIL)。
 
? Java 字节码是通过称为 Java 虚拟机 (JVM) 的应用程序执行的。类似地,已编译的 C# 程序由公共语言运行库 (Common Language Runtime, CLR) 执行。
 
? 除了一些细微的差别以外,C# 中的异常处理与 Java 非常相似。C# 用 try...catch 构造来处理运行时错误(也称为异常),这和 Java 中是完全一样的。System.Exception 类是所有 C# 异常类的基类。
 
? 同 Java 一样,C# 是强类型检查编程语言。编译器能够检测在运行时可能会出现问题的类型错误。
 
? 同 Java 一样,C# 提供自动垃圾回收功能,从而使编程人员避免了跟踪分配的资源。
 
? Java 和 C# 都支持单一继承和多接口实现。

现在让我们看一看本文涵盖的重要差异:

? C# 语言引入了一些新的语言构造,如 foreach、索引器、属性、委托、运算符重载和其他语言构造。在本文后面我们将更详细地讨论这些构造。
 

本页内容
 源文件约定
 顶层声明
 完全限定名和命名空间别名
 预处理指令
 语言语法
 转换和强制转换
 值类型和引用类型
 装箱 (Boxing) 和拆箱 (Unboxing)
 运算符
 流程控制
 类基础
 Main() 方法
 其他方法
 使用不确定数目的参数
 属性
 结构
 C# 中的数组
 继承和派生类
 将类型强制转换到基类
 选择构造函数
 方法重写
 抽象类
 接口
 运算符重载
 异常
 高级 C# 技术
 垃圾回收
 安全代码和不安全代码
 小结

源文件约定
我们需要知道,两种语言在源程序的文件命名约定和结构上有一些不同:

文件命名
包含 C# 类的文件的命名约定与 Java 有点不同。首先,在 Java 中,所有源文件的扩展名都为 .java。每个源文件都包含一个顶层公共类声明,并且类名必须与文件名相匹配。换句话说,一个用公共范围声明的名为 Customer 的类必须定义在具有名称 Customer.java 的源文件中。

而 C# 源代码是由 .cs 扩展名表示的。与 Java 不同,源文件可以包含多个顶层公共类声明,而文件名不需要与任何类名相匹配。

返回页首
顶层声明
在 Java 和 C# 中,源代码以按一定顺序排列的顶层声明开始。Java 和 C# 程序中的声明只存在少许差别。

Java 中的顶层声明
在 Java 中,我们可以用 package 关键字将类组合在一起。打包的类必须在源文件的第一个可执行的行中使用 package 关键字。接着出现的是需要访问其他包中的类的任何导入语句,之后是类声明,比如:

package ;
import .;
class Customer
{
  ...
}

C# 中的顶层声明
C# 使用命名空间的概念,通过 namespace 关键字将逻辑上相关的类组合在一起。这些做法类似于 Java 包,而具有相同名称的类可以出现在两个不同的命名空间中。要访问定义在当前命名空间之外的命名空间中的类,我们可以使用紧跟该命名空间名的 using 关键字,如下所示:

using .;
namespace 
{
  class Customer
  {
    ...
  }
}

注意,using 语句可以完全合法地放在命名空间声明中,在这种情况下,这样导入的命名空间就形成了包含命名空间的一部分。

Java 不允许在相同的源文件中有多个包,而 C# 允许在一个 .cs 文件中有多个命名空间:

namespace AcmeAccounting
{
  public class GetDetails
  {
    ...
  }
}
namespace AcmeFinance
{
  public class ShowDetails
  {
    ...
  }
}

返回页首
完全限定名和命名空间别名
同 Java 一样,通过提供类的完全限定名(如 System.Data.DataSet 或上面的示例中的 AcmeAccounting.GetDetails),我们可以在没有命名空间的 using 引用的情况下访问 .NET 或用户定义的命名空间中的类。

完全限定名可能会变得很长而不便于使用,在这种情况下,我们可以使用 using 关键字来指定一个简称或别名,以提高代码的可读性。

在下面的代码中,创建了一个别名来引用由一个虚构的公司所编写的代码:

using DataTier = Acme.SQLCode.Client;
using System;
public class OutputSales
{
  public static void Main()
  {
    int sales = DataTier.GetSales("January");
    Console.WriteLine("January's Sales: {0}", sales);
  }
}

注意 WriteLine() 的语法,格式字符串中带有 {x},其中 x 表示在此处要插入的值的参数列表的位置。假定 GetSales() 方法返回 500,则该应用程序的输出将为:

January's Sales: 500

返回页首
预处理指令
与 C 和 C++ 相似,C# 包括预处理器指令,预处理器指令提供了有条件地跳过源文件的某些部分、报告错误和警告条件,以及描述源代码的不同部分的能力。使用“预处理指令”这个术语只是为了与 C 和 C++ 编程语言保持一致,因为 C# 并不包括单独的预处理步骤。有关 C# 预处理器指令的完整列表,请参见 C# 预处理器指令。

返回页首
语言语法
在这一部分中,我们讨论这两种语言之间的相似点和不同点。一些主要的不同点有:

? 常量声明— Java 为此而使用 final 关键字,而 C# 使用关键字 const 或 readonly。
 
? 复合数据类型— 在 Java 中,我们可以使用类关键字来创建作为没有方法的类的复合数据类型,但是 C# 为此提供了 struct,同 C 中一样。
 
? 析构函数— C# 允许我们创建在销毁类的实例之前调用的析构函数方法。在 Java 中,可以提供 finalize() 方法来包含在将对象作为垃圾回收之前清除资源的代码。在 C# 中,由类析构函数来提供此功能。析构函数类似一个没有参数并前面带有波形符“~”的构造函数。
 
? 函数指针 — C# 提供一个称为 delegate 的构造来创建类型安全的函数指针。Java 没有任何与之对等的机制。

posted on 2006-05-17 23:27  Vinson  阅读(432)  评论(1编辑  收藏  举报