此程序的输出告诉我们,结果是 System.Double 类型,选择它是因为System.Math.PI 是这种类型。
Calculated area is = 201.061929829747
The result is of type System.Double
流程控制
在这两种语言中,流程控制语句是非常相似的,但是这一部分也会讨论它们的一些细微差别。
分支语句
分支语句根据特定的条件改变运行时程序执行的流程。
if、else 和 else if
这些在两种语言中是一样的。
switch 语句
在两种语言中,switch 语句都提供条件多分支操作。但是有点不同的是,Java 允许您“越过”一个 case 并执行下一个 case,除非您在 case 的末尾使用了 break 语句。然而,C# 需要在每个 case 的末尾都使用 break 或 goto 语句,如果两者都不存在,则编译器会产生下列错误:
Control cannot fall through from one case label to another.
不过请注意,在没有指定要执行的代码的地方,当 case 匹配时,控制会越过随后的 case。当在 switch 语句中使用 goto 时,我们只能跳至同一 switch 中的另一个 case 块。如果我们想要跳至 default case,我们可以使用“goto default;”,否则,我们需要使用“goto case cond;”,其中 cond 是我们希望跳至的 case 的匹配条件。Java 的 switch 语句的另一个不同之处在于,在 Java 中,我们只能对整数类型使用 switch 语句,而 C# 允许我们对字符串变量使用 switch 语句。
例如,下面的程序在 C# 中是合法的,但在 Java 中却是不合法的:
switch (args[0])
{
case "copy":
...
break;
case "move":
...
goto case "delete";
break;
case "del":
case "remove":
case "delete":
...
break;
default:
...
break;
}
goto 的返回
在 Java 中,goto 是一个没有实现的保留关键字。然而,我们可以使用带有 break 或 continue 标签的语句来达到与 goto 相似的目的。
C# 允许 goto 语句跳至带有标签的语句。不过请注意,为了跳至一个特定的标签,goto 语句必须在该标签的范围内。换句话说,goto 不可用来跳进一个语句块(不过,它可以跳出一个语句块)、跳出一个类,或退出 try...catch 语句中的 finally 块。不过请注意,在大多数情况下,我们都不鼓励您使用 goto,因为它违反了面向对象编程的良好实践。
循环语句
循环语句重复指定的代码块,直到满足给定的条件为止。
for 循环
在两种语言中,for 循环的语法和操作均相同:
for (initialization; condition; expression)
statement;
foreach 循环
C# 引入了一种新的循环类型,称为 foreach 循环(类似于 Visual Basic 的 For Each)。foreach 循环允许遍历支持 IEnumerable 接口的容器类中的每一项(例如:数组)。下面的代码说明了如何使用 foreach 语句来输出一个数组的内容:
public static void Main()
{
int[] arr1= new int[] {1,2,3,4,5,6};
foreach ( int i in arr1)
{
Console.WriteLine("Value is {0}", i);
}
}
在 C# 中的数组部分,我们将更详细地介绍 C# 中的数组。
while 和 do...while 循环
在两种语言中,while 和 do...while 语句的语法和操作均相同:
while (condition)
{
//statements
}
As usual, don't forget the trailing ; in do...while loops:
do
{
//statements
}
while(condition);
类基础
访问修饰符
C# 中的修饰符与 Java 大致相同,我们将在这一部分介绍其中的一些细微差别。每个类成员或类本身都可以用访问修饰符进行声明,以定义许可访问的范围。没有在其他类中声明的类只能指定 public 或 internal 修饰符,而嵌套的类(如其他的类成员)可以指定下面五个修饰符中的任何一个:
public ― 对所有类可见
protected ―仅从派生类中可见
private ― 仅在给定的类中可见
internal ― 仅在相同的程序集中可见
protected internal ― 仅对当前的程序集或从包含类中派生的类型可见
public、protected 和 private 修饰符
public 修饰符使得可以从类内外的任何地方访问成员。protected 修饰符表示访问仅限于包含类或从它派生的类。private 修饰符意味着只可能从包含类型中进行访问。
internal 修饰符
internal 项只可以在当前的程序集中进行访问。.NET 中的程序集大致等同于 Java 的 JAR 文件,它表示可以从中构造其他程序的生成块。
protected internal 修饰符
protected internal 项仅对当前程序集或从包含类派生的类型可见。在 C# 中,默认访问修饰符是 private,而 Java 的默认访问修饰符是包范围。
sealed 修饰符
在其类声明中带有 sealed 修饰符的类可以认为是与抽象类完全相反的类 ― 它不能被继承。我们可以将一个类标记为 sealed,以防止其他类重写它的功能。自然地,sealed 类不能是抽象的。同时还需要注意,该结构是隐式密封的;因此,它们不能被继承。sealed 修饰符相当于在 Java 中用 final 关键字标记类。
readonly 修饰符
要在 C# 中定义常量,我们可以使用 const 或 readonly 修饰符替换 Java 的 final 关键字。在 C# 中,这两个修饰符之间的区别在于,const 项是在编译时处理的,而 readonly 字段是在运行时设置的。这可以允许我们修改用于在运行时确定 readonly 字段值的表达式。
这意味着给 readonly 字段的赋值可以出现在类构造函数及声明中。例如,下面的类声明了一个名为 IntegerVariable 的 readonly 变量,它是在类构造函数中初始化的:
using System;
public class ReadOnlyClass
{
private readonly int IntegerConstant;
public ReadOnlyClass ()
{
IntegerConstant = 5;
}
// We get a compile time error if we try to set the value of the readonly
//
class variable outside of the constructor
public int IntMember
{
set
{
IntegerConstant = value;
}
get
{
return IntegerConstant;
}
}
public static void Main(string[] args)
{
ReadOnlyClass obj= new ReadOnlyClass();
// We cannot perform this operation on a readonly field
obj.IntMember = 100;
Console.WriteLine("Value of IntegerConstant field is {0}",
obj.IntMember);
}
}
注意,如果 readonly 修饰符应用于静态字段,它就应该在该静态字段中进行初始化。
类的构造函数。
Main() 方法
每个 C# 应用程序都必须http://msdn.microsoft.com/vstudio/java/gettingstarted/csharpforjava/#Arrays in C#只能包含一个 Main() 方法,Main() 方法指定程序从何处开始执行。注意,在 C# 中,Main() 用大写字母开头,而 Java 使用小写的 main()。
Main() 只能返回 int 或 void,并且有一个可选的字符串数组参数来表示命令行参数:
static int Main (string[] args)
{
...
return 0;
}
字符串数组参数可以包含任何传入的命令行参数,这与 Java 中完全一样。因此,args[0] 指定第一个命令行参数,而 args[1] 表示第二个参数,等等。与 C++ 不同的是,args 数组不包含 EXE 文件的名称。
其他方法
当将参数传递给方法时,它们可能通过值传递,也可能通过引用传递。值参数只提取任何变量的值以在方法中使用,因而调用代码中的变量值不受方法中对这些参数所执行的操作的影响。
而引用型参数指向在调用代码中声明的变量,因而在通过引用传递时,方法将修改该变量的内容。
通过引用传递
在 Java 和 C# 中,引用对象的方法参数总是通过引用传递,而基本数据类型参数则通过值传递。
在 C# 中,所有参数在默认情况下都是通过值传递的。要通过引用进行传递,我们需要指定关键字 ref 或 out 中的一个。这两个关键字的不同之处在于参数的初始化。ref 参数必须在使用前进行初始化,而 out 参数无需在传递前进行显式初始化,并且任何先前的值都会被忽略。
请注意,当方法将引用类型作为参数使用时,引用本身是通过值传递的。然而,引用仍然指向内存中的同一对象,因此对对象的属性所做的任何改变在方法退出之后将保持不变。但是,因为引用本身是通过值传递的,所以在方法内它应该改为指向一个不同的对象甚至一个新对象,而一旦方法执行完毕,引用就会恢复为指向原来的对象,即使原来的对象是未赋值的也同样如此。
ref 关键字
当我们希望调用