变量表示了存储位置。每一个变量都属于某个类型,这个类型决定了变量能保存什么样的值。

局部变量是指在函数型成员如方法、属性、索引器中声明的变量。
声明一个局部变量,需要指定一个类型名,一个代表变量名字的说明符,以及一个可选的初始值。
比如:
 int a;
 int b = 1;

可以在一个局部变量的声明中包含多个变量的名字。上面的a和b可以定义成
int a, b = 1;

一个变量必须先赋值,才能取出它的值。
例子:
1 class Test
2 {
3 static void Main() {
4 int a;
5 int b = 1;
6 int c = a + b; // 错误,a还没有赋值。
7 
8 }
9 }

会导致编译错误,因为这个程序使用了一个未赋值的变量。
明确的赋值过程将在12.3节中定义。
一个字段(见17.4节)是指一个和类或者结构相关联的变量(译注:静态变量),或者是和类或结构的实例相关联的变量(译注:实例变量)。
声明时指定了static修饰符的字段就是静态变量,没有指定static修饰符的就是实例变量。
一个静态变量是和和一个类相关联的,而一个实例变量是和一个实例相关联的。
举例说明:
1 using Personnel.Data;
2 class Employee
3 {
4 private static DataSet ds;
5 public string Name;
6 public decimal Salary;
7 
8 }

Employee类包含一个私有的静态变量和两个公开的实例变量。
形式参数声明也会定义变量。C#中一共有四种类型的参数:值参数,引用参数,输出参数,参数数组。
一个值参数是用来传递"输入"的参数,这种情况下,一个实际参数的值(译注:通过形式参数)被传入方法内,在方法内部改变形式参数的值不会影响原来那个实际参数。
一个形式值参代表它自己的那个变量,这个变量和相应的实际参数没有关系。
例子:
 1 using System;
 2 class Test
 3 {
 4 static void F(int p) {
 5 Console.WriteLine("p = {0}", p);
 6 p++;
 7 }
 8 static void Main() {
 9 int a = 1;
10 Console.WriteLine("调用前: a = {0}", a);
11 F(a);
12 Console.WriteLine("调用后: a = {0}", a);
13 }
14 }

例子中方法F包含一个值参数p。这个例子输出:

1 调用前: a = 1
2 = 1
3 调用后: a = 1

虽然值参数p被修改了。
一个引用参数是用来传递"引用"的参数,这种情况下,形式参数作为实际参数的一个别名。一个引用参数自己不会定义一个变量,只是引用相应的实际参数。
改变一个引用参数,将影响相应的实际参数。
引用参数需要指定ref修饰符。例子:
 1 using System;
 2 class Test
 3 {
 4 static void Swap(ref int a, ref int b) {
 5 int t = a;
 6 = b;
 7 = t;
 8 }
 9 static void Main() {
10 int x = 1;
11 int y = 2;
12 Console.WriteLine("调用前: x = {0}, y = {1}", x, y);
13 Swap(ref x, ref y);
14 Console.WriteLine("调用后: x = {0}, y = {1}", x, y);
15 }
16 }

Swap方法有两个引用参数。
输出:
1 调用前: x = 1, y = 2
2 调用后: x = 2, y = 1

ref关键字在定义形参和调用方法是都要指定。
调用是指定ref关键字,是为了提醒读代码开发人员,这个实际参数的值在方法调用之后可能会改变。
输出参数和引用参数类似,只是输出参数不看重实际参数的初始值(译注:表明这个参数主要用来接收方法的"输出",而不是给方法提供输入,换句话说,out参数允许方法返回多个值)。输出参数需要指定关键字out。
例子:
 1 using System;
 2 class Test
 3 {
 4 static void Divide(int a, int b, out int result, out int remainder) {
 5 result = a / b;
 6 remainder = a % b;
 7 }
 8 static void Main() {
 9 for (int i = 1; i < 10; i++)
10 for (int j = 1; j < 10; j++) {
11 int ans, r;
12 Divide(i, j, out ans, out r);
13 Console.WriteLine("{0} / {1} = {2}r{3}", i, j, ans, r);
14 }
15 }
16 }

Divide方法包含两个输出参数,一个用来保存商,一个用来保存余数。
(译注:ref和out参数在调用是必须是可以赋值的变量。换句话说,不能传入一个常量如F(ref 2),也不能传入一个readonly的只读字段或传入一个const常量)
对于值参数,引用参数,输出参数,形式参数和实际参数是一一对应的,
参数数组允许多对一:多个实际参数可以对应一个参数数组。换句话说,参数数组允许方法的参数列表的长度是可变的。
参数数组需要指定params修饰符。对于某个特定的方法来说,它只能有一个参数数组,并且参数数组必须是它的最后一个参数(译注:参数数组也只是方法的一个参数)。
调用时,既可以传入单个的类型相同的数组,或者任意个和数组元素的类型相同的参数。
举例说明:
 1 class Test
 2 {
 3 static void F(params int[] args) {
 4 Console.WriteLine("# of arguments: {0}", args.Length);
 5 for (int i = 0; i < args.Length; i++)
 6 Console.WriteLine("\targs[{0}] = {1}", i, args[i]);
 7 }
 8 static void Main() {
 9 F();
10 F(1);
11 F(12);
12 F(123);
13 F(new int[] {1234});
14 }
15 }

方法F接收可变数量的参数,可以用多种方式调用这个方法。
输出:
 1 # of arguments: 0
 2 # of arguments: 1
 3 args[0= 1
 4 # of arguments: 2
 5 args[0= 1
 6 args[1= 2
 7 # of arguments: 3
 8 args[0= 1
 9 args[1= 2
10 args[2= 3
11 # of arguments: 4
12 args[0= 1
13 args[1= 2
14 args[2= 3
15 args[3= 4

这部分介绍内容里大部分例子用到了Console类的WriteLine方法。
这个方法的参数替换功能,如例子中的:
1 int a = 1, b = 2;
2 Console.WriteLine("a = {0}, b = {1}", a, b);

是通过参数数组来实现的。
WriteLine方法有多个重载的版本,其中有接收少量参数的版本,一个版本包含了参数数组(译注:因此可以包含任意数量的参数)。
 1 namespace System
 2 {
 3 public class Console
 4 {
 5 public static void WriteLine(string s) {…}
 6 public static void WriteLine(string s, object a) {…}
 7 public static void WriteLine(string s, object a, object b) {…}
 8 
 9 public static void WriteLine(string s, params object[] args) {…}
10 }
11 }



posted on 2009-03-19 22:18  apple123  阅读(409)  评论(0编辑  收藏  举报