一:參數數組
C#允許爲函數指定一個(只能指定一個)特殊參數,這個參數必須是函數定義中的最後一個參數,稱爲參數數組。參數數組允許使用個數不定的參數調用函數,可以使用params關鍵字定義它們。例如:
static int sumVal(params int[] vals)
{
int sum = 0;
foreach(int val in vals){
sum += val;
}
return sum;
}
static void Main(string[] args)
{
int sum = sumVal(1, 5, 2, 8, 9);
Console.WriteLine("Summed Value = {0}", sum);
Console.ReadKey();
}
二:傳值調用
C#和C/C++一樣,默認的也是傳值調用函數
三:使用引用來傳遞函數參數
C++當中有引用的機制,C#當中也有。在C#當中使用ref關鍵字來指定參數,使其成爲引用。關於引用的好處,在學習C++時就已經瞭解過。注意在C#當中,在函數的定義和函數的調用時都得使用ref關鍵字來指定。如下:
static void ShowDouble(ref int val)
{
val *= 2;
Console.WriteLine("val doubled = {0}", val);
}
static void Main(string[] args)
{
int val = 5;
ShowDouble(ref val);
Console.ReadKey();
}
注意用作ref參數的變量有兩個限制:1,必須在函數調用中使用“非常量”。2,變量必須是已經初始化過的。
四:輸出參數
使用out關鍵字,所指定的參數是一個輸出參數。Out關鍵字的使用方式與ref相同。該參數的值將返回給函數調用中使用的變量。
Out與ref的區別如下:
把未賦值的變量作ref參數是非法的,但可以將未賦值的變量用作out參數
在函數使用out參數時,必須把它看成是尚未賦值的。
注意:可以把已賦值的變量用作out參數,但存儲在該變量中的值會在函數執行時丟失。
例如:
static int MaxValue(int[] intArray, out int maxIndex)
{
int maxVal = intArray[0];
maxIndex = 0;
for (int i = 0; i < intArray.Length; i++)
{
if (intArray[i] > maxVal)
{
maxVal = intArray[i];
maxIndex = i;
}
}
return maxVal;
}
五:變量作用域
關於變量作用域,看一個出錯的例子。代碼如下:
int i;
string text;
for (i = 0; i < 10; i++)
{
text = "Line " + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
出錯原因:必須在使用變量之前對其進行初始化,但text只在for循環中初始化。由於沒有在循環外進行初始化,付給text的值在循環塊退出時就丟失了。可以將程序改正如下即可。
int i;
string text = "";
for (i = 0; i < 10; i++)
{
text = "Line " + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
六:結構函數
結構函數與C++當中帶函數的結構體是類似的。也即是在結構類型當中不僅可以包含數據,還可以包含函數。如下:
struct CustomerName
{
public string firstName, lastName;
public string name()
{
return firstName + " " + lastName;
}
}
七:函數的重載
函數的重載與C++中的函數重載也類似。
八:委託(delegate)
委託是一種存儲函數引用的類型。
委託的聲明類似於函數,但不帶函數體,而且要使用關鍵字delegate。委託的聲明指定了一個返回類型和一個參數列表。
定義了委託之後,就可以聲明該委託類型的變量。接着把這個變量初始化爲與委託具有相同返回類型和參數列表的函數引用。之後,就可以使用委託變量調用這個函數,就像該變量是一個函數一樣。
有了引用函數的變量之後,就可以執行不能用其他方式完成的操作。例如,可以把委託變量作爲參數傳遞給一個函數,這樣,該函數就可以使用委託調用它引用的任何函數,而且在運行之前不必知道調用的是哪個函數。如下面的例子:
static void Main(string[] args)
{
ProcessDelegate process;
Console.WriteLine("Enter 2 numbers separated with a comma:");
string input = Console.ReadLine();
int commaPos = input.IndexOf(",");
double param1 = Convert.ToDouble(input.Substring(0, commaPos));
double param2 = Convert.ToDouble(input.Substring(commaPos + 1, input.Length - commaPos - 1));
Console.WriteLine("Enter M to multiply or D to divide:");
input = Console.ReadLine();
if (input == "M")
{
process = new ProcessDelegate(Multiply);
}
else
{
process = new ProcessDelegate(Divide);
}
Console.WriteLine("Result: {0}", process(param1, param2));
Console.ReadKey();
}