變數|規範
變數表示儲存位置。每個變數都屬於一種類型,它確定什麼樣的值可以儲存在該變數中。局部變數是在方法、屬性或索引器中聲明的變數。局部變數是通過指定類型名稱和聲明符(它指定變數名和可選的初始值)定義的,如:
int a;
int b = 1;
但局部變數聲明也可以包含多個聲明符。a 和 b 的聲明可以重寫為:
int a, b = 1;
一個變數必須先賦值,然後才能使用它的值。樣本
class Test
{
static void Main() {
int a;
int b = 1;
int c = a + b; // error, a not yet assigned
...
}
}
導致編譯時間錯誤,因為它試圖在給變數 a 賦值之前使用它。
欄位是與類或結構或與類或結構的執行個體關聯的變數。用 static 修飾符聲明的欄位定義靜態變數,不用此修飾符聲明的欄位則定義執行個體變數。靜態欄位與類型關聯,而執行個體變數與執行個體關聯。樣本
using Personnel.Data;
class Employee
{
private static DataSet ds;
public string Name;
public decimal Salary;
...
}
顯示了具有一個私人靜態變數和兩個公用執行個體變數的 Employee 類。
形參聲明也定義變數。有四種類型的參數:值參數、引用參數、輸出參數和參數數組。
值參用於“in”參數傳遞。在此過程中,自變數的值被傳入方法中。因為一個值參在方法中用自己的變數儲存(而非原自變數),所以對此參數的修改不會影響到原自變數。值參的變數是通過複製原自變數的值來初始化的。樣本
using System;
class Test {
static void F(int p) {
Console.WriteLine("p = {0}", p);
p++;
}
static void Main() {
int a = 1;
Console.WriteLine("pre: a = {0}", a);
F(a);
Console.WriteLine("post: a = {0}", a);
}
}
顯示了一個具有名為 p 的值參數的方法 F。樣本輸出結果如下
pre: a = 1
p = 1
post: a = 1
即使值參數 p 已修改。
“引用參數”用於“by reference”參數傳遞。在此過程中,“引用參數”就是調用者提供的自變數的別名。“引用參數”並不定義自己的變數,而是直接引用原自變數,因此對“引用參數”的修改就將直接影響相應原自變數的值。引用參數用 ref 修飾符來聲明。樣本
using System;
class Test {
static void Swap(ref int a, ref int b) {
int t = a;
a = b;
b = t;
}
static void Main() {
int x = 1;
int y = 2;
Console.WriteLine("pre: x = {0}, y = {1}", x, y);
Swap(ref x, ref y);
Console.WriteLine("post: x = {0}, y = {1}", x, y);
}
}
顯示了一個具有兩個引用參數的 Swap 方法。產生的輸出為:
pre: x = 1, y = 2
post: x = 2, y = 1
在形參聲明和形參的使用中都必須使用 ref 關鍵字。在調用位置使用 ref 可以引起對參數的特別注意,這樣閱讀代碼的開發人員就會知道參數值可以因調用而更改。
對於輸出參數來說,調用者提供的自變數的初始值並不重要,除此之外,輸出參數與引用參數類似。輸出參數是用 out 修飾符聲明的。樣本
using System;
class Test {
static void Divide(int a, int b, out int result, out int remainder) {
result = a / b;
remainder = a % b;
}
static void Main() {
for (int i = 1; i < 10; i++)
for (int j = 1; j < 10; j++) {
int ans, r;
Divide(i, j, out ans, out r);
Console.WriteLine("{0} / {1} = {2}r{3}", i, j, ans, r);
}
}
}
顯示了一個 Divide 方法,該方法包含兩個輸出參數:一個參數用於除法的結果,另一個參數用於餘數。
對於值、引用和輸出這三種類型的參數,在調用方提供的自變數和用於表示它們的參數之間存在一對一的對應關係。參數數組則允許存在多對一關聯性:多個參數可以用一個自變數來表示。換言之,參數數組允許可變長度的自變數列表。
參數數組用 params 修飾符聲明。一個給定的方法只能有一個參數數組,而且它必須始終是最後一個指定的參數。參數數組的類型總是一維數群組類型。調用方可以傳遞一個屬同一類型的陣列變數,或任意多個與該數組的元素屬同一類型的自變數。例如,樣本
using System;
class Test
{
static void F(params int[] args) {
Console.WriteLine("# of arguments: {0}", args.Length);
for (int i = 0; i < args.Length; i++)
Console.WriteLine("\targs[{0}] = {1}", i, args[i]);
}
static void Main() {
F();
F(1);
F(1, 2);
F(1, 2, 3);
F(new int[] {1, 2, 3, 4});
}
}
顯示了帶數目可變的 int 參數的方法 F,以及對此方法的若干個調用。輸出為:
# of arguments: 0
# of arguments: 1
args[0] = 1
# of arguments: 2
args[0] = 1
args[1] = 2
# of arguments: 3
args[0] = 1
args[1] = 2
args[2] = 3
# of arguments: 4
args[0] = 1
args[1] = 2
args[2] = 3
args[3] = 4
此介紹中出現的大部分樣本使用 Console 類的 WriteLine 方法。此方法的參數替換行為(如下面的樣本所示)
int a = 1, b = 2;
Console.WriteLine("a = {0}, b = {1}", a, b);
是使用參數數組完成的。為適應常見的各種需要,WriteLine 方法有若干個重載的方法供選用,這些方法中,有些需傳遞固定個數的參數,有些使用了參數數組。
namespace System
{
public class Console
{
public static void WriteLine(string s) {...}
public static void WriteLine(string s, object a) {...}
public static void WriteLine(string s, object a, object b) {...}
...
public static void WriteLine(string s, params object[] args) {...}
}
}