C#教程第五課:方法

來源:互聯網
上載者:User
教程 本節課向你介紹C#的方法,其目的是:
1.瞭解方法的結構格式

2.瞭解靜態和執行個體方法之間的區別

3.學會執行個體對象的使用

4.學會如何調用執行個體化的對象

5.學會方法的四種參數類型的使用

6.學會使用"this"引用

以往,對於每個程式來說,所有的工作都在Main()方法中實現。這對於功能簡單的程式是合適的,因為僅僅用來學習一些概念。有個更好的方法來組織你的程式,那就是使用方法。方法是很有用的,因為方法可以讓你在不同的單元中分開設計你的邏輯模組。

方法的結構格式如下:

屬性 修飾符 傳回值類型 方法名(參數) { 語句 }

我們將在後面的課程中,討論屬性和修飾符。方法的傳回值可以是任何一種C#的資料類型,該傳回值可以賦給變數,以便在程式的後面部分使用。方法名是唯一,可以被程式調用。為使得你的代碼變得更容易理解和記憶,方法的取名可以同所要進行的操作聯絡起來。你可以傳遞資料給方法,也可以從方法中返回資料。它們由大括弧包圍起來。大括弧中的語句實現了方法的功能。

1.清單5-1. 一個簡單的方法: OneMethod.cs

using System;
class OneMethod {
public static void Main() {
string myChoice;
OneMethod om = new OneMethod();

do {
myChoice = om.getChoice();
// Make a decision based on the user's choice
switch(myChoice) {
case "A":
case "a":
Console.WriteLine("You wish to add an address.");
break;
case "D":
case "d":
Console.WriteLine("You wish to delete an address.");
break;
case "M":
case "m":
Console.WriteLine("You wish to modify an address.");
break;
case "V":
case "v":
Console.WriteLine("You wish to view the address list.");
break;
case "Q":
case "q":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("{0} is not a valid choice", myChoice);
}

// Pause to allow the user to see the results
Console.Write("Press any key to continue...");
Console.ReadLine();
Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit
}

string getChoice() {
string myChoice;
// Print A Menu
Console.WriteLine("My Address Book\n");
Console.WriteLine("A - Add New Address");
Console.WriteLine("D - Delete Address");
Console.WriteLine("M - Modify Address");
Console.WriteLine("V - View Addresses");
Console.WriteLine("Q - Quit\n");
Console.WriteLine("Choice (A,D,M,V,or Q): ");

// Retrieve the user's choice
myChoice = Console.ReadLine();
return myChoice;
}
}

說明

1.清單5-1中的程式類似於第四課中的DoLoop程式。

區別在於:前一課中的程式列印出菜單內容,並在Main()方法中接受使用者的輸入,而本課中,該功能用一個名為getChoice()的方法實現,該方法的傳回值類型是個字串類型。在main方法中,在switch語句中用到了該串。方法"getChoice"實現了調用時所完成的工作。方法名後面的括弧內是空的,因為調用getChoice()方法時,不需要傳遞任何資料。

2.在方法塊中,我們首先定義了變數"myChoice"。

雖然它與 Main()方法中的"myChoice"變數同名同類型, 但它們是不同的兩個變數,因為局部變數僅僅在其定義的塊內可見。換句話說, getChoice()方法中的"myChoice" 同Main()方法中的"myChoice"變數沒有絲毫聯絡。getChoice()方法列印出一個菜單到控制台,並讀取使用者的輸入。"return" 語句把"myChoice"變數值返回給Main()方法中的調用者getChoice()。注意: "return"語句傳回型別同該方法中定義的傳回值類型相同,本例中,該傳回值是個字串。

3.在Main()方法中,在使用getChoice()之前,執行個體化了一個新的"OneMethod"對象。

這是因為:我們沒有指明一個"靜態"修飾符。(注意:Main()函數帶有"靜態"修飾符),getChoice()就成為一個執行個體的方法。 執行個體方法和靜態方法的區別是:前者可以建立多個類的執行個體,每個執行個體有自己的單獨的getChoice()方法。而一旦方法是靜態,就不存在方法的執行個體,你只能調用該靜態方法的一個實現。

所以,正如前面所講的,因為getChoice()並不是靜態,所以,我們必須執行個體化一個新對象來使用它。這是通過定義"OneMethod om = new OneMethod()"來進行的。在等號的左邊,是對象引用"om",其類型是OneMethod。"om"是個對象的引用,這點很重要,"om"並不是對象自身,它是個引用OneMethod類型對象的變數。 在等號的右邊,把新建立的OneMethod對象賦給引用"om"。 關鍵字"new"是個在堆上建立對象的新執行個體的C#運算子。此處完成的工作是: 在堆上建立一個新的OneMethod執行個體,並把它賦給om引用。一旦有了om引用的OneMethod對象執行個體,就可以通過om引用來對執行個體進行處理。

方法,域和其他類成員可以通過"." (點)運算子進行訪問,標識和操縱。一旦需要調用方法getChoice(),就通過om引用,並使用點運算子"om.getChoice()"來進行。 getChoice() 塊中的語句執行完畢之後即返回。為了捕捉到getChoice()的傳回值,我們使用了賦值運算子"="。 返回串放到了Main()函數的局部變數 myChoice中,從那裡,程式的其餘部分按照前面課程中介紹的方式正常執行。

2.清單5-2. 方法參數:MethodParams.cs

using System;
class Address {
public string name;
public string address;
}
class MethodParams {

public static void Main() {
string myChoice;
MethodParams mp = new MethodParams();
do {
// show menu and get input from user
myChoice = mp.getChoice();
// Make a decision based on the user's choice
mp.makeDecision(myChoice);
// Pause to allow the user to see the results
Console.Write("Press any key to continue...");
Console.ReadLine();
Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit
}

// show menu and get user's choice
string getChoice() {
string myChoice;
// Print A Menu
Console.WriteLine("My Address Book\n");
Console.WriteLine("A - Add New Address");
Console.WriteLine("D - Delete Address");
Console.WriteLine("M - Modify Address");
Console.WriteLine("V - View Addresses");
Console.WriteLine("Q - Quit\n");
Console.WriteLine("Choice (A,D,M,V,or Q): ");
// Retrieve the user's choice
myChoice = Console.ReadLine();
return myChoice;
}

// make decision
void makeDecision(string myChoice) {
Address addr = new Address();
switch(myChoice) {
case "A":
case "a":
addr.name = "Joe";
addr.address = "C# Station";
this.addAddress(ref addr);
break;
case "D":
case "d":
addr.name = "Robert";
this.deleteAddress(addr.name);
break;
case "M":
case "m":
addr.name = "Matt";
this.modifyAddress(out addr);
Console.WriteLine("Name is now {0}.", addr.name);
break;
case "V":
case "v":
this.viewAddresses("Cheryl", "Joe", "Matt", "Robert");
break;
case "Q":
case "q":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("{0} is not a valid choice", myChoice);
}
}

// insert an address
void addAddress(ref Address addr) {
Console.WriteLine("Name: {0}, Address: {1} added.", addr.name, addr.address);
}
// remove an address
void deleteAddress(string name) {
Console.WriteLine("You wish to delete {0}'s address.", name);
}
// change an address
void modifyAddress(out Address addr) {
//Console.WriteLine("Name: {0}.", addr.name); // causes error!
addr = new Address();
addr.name = "Joe";
addr.address = "C# Station";
}
// show addresses
void viewAddresses(params string[] names) {
foreach (string name in names) {
Console.WriteLine("Name: {0}", name);
}
}
}

說明

1.清單5-2是清單5-1的修改,主要是對程式進行了模組化,並添加了更多的實現,以便闡述參數傳遞的用法。

C#可以處理四種類型的參數:out(輸出),ref(引用),params(數組)和value(值)。為了說明參數的用法,我們用兩個字串域建立地址類。

2.在Main()方法中,我們調用getChoice()來讀取使用者的輸入,並且把字串放到myChoice變數中。

之後,把myChoice變數作為makeDecision()函數的實在參數。在實現makeDecision()方法時,注意其形式參數為字串myChoice。需要再次說明的是:這是個新的myChoice變數,不同於調用者的實在參數,僅僅是適用於本方法的局部變數。 因為makeDecision()方法的myChoice參數沒有任何其他修飾符,故認為它是"值"參,即實在參數的值被拷貝到棧中,故作為值參的變數是局部的,任何對局部變數值的改變並不影響到調用者的實在參數的值。換句話說,值參僅僅是來自調用者的輸入。

3.makeDecision()方法中的switch陳述式完成如下功能:

在每種情形下,都調用相應的方法。這些方法的調用不同於Main()方法。除了使用"mp" 引用,它們還使用了"this"關鍵字。"this"是對當前對象的引用。由於makeDecision()方法不是靜態方法,當前對象已經被執行個體化,所以可以使用"this"引用來調用同一執行個體中的方法。

4.addAddress()方法用到了"ref"參數,即引用可作為參數來傳遞,即該引用被拷貝到棧中,其引用的對象同調用者的實參所引用的對象是同一個。

這意味著:任何對局部引用的對象的改變也就是對調用者所引用的對象的改變。你可以想象一下,這就相當於輸入/輸出參數。

5.modifyAddress()中有一個輸出參數。

輸出參數僅僅傳遞給被調用函數。一旦調用該方法時,在棧中的僅有的一個引用未被賦值,因為根據賦值的確定性原則,在該變數沒有被賦值之前,就不能使用該變數。modifyAddress()方法的第一行作為注釋,說明了這一點。你可以試著去掉注釋符,編譯一下程式,看看結果如何。一旦該變數被賦了值,在程式返回之後,輸出參數就被拷貝到調用者的參數中。所以,在方法返回之前,必須給輸出參數賦值。

小結
C# 語言的一個很有用途的參數類型是數組參數,它須是一維或多維的數組。在makeDecision()方法中,我們傳遞了用四個逗號隔開的字串參數。參數的個數是變數。在viewAddresses()方法中,使用了foreach迴圈,逐一輸出這些字串。數組參數僅是一種輸入性質的參數,任何對數組參數值的改變僅僅影響到局部的副本值。

概括地講,你現在已經理解了方法的組織圖。你還瞭解了方法的實現可以採用的四種參數類型及其格式。 一旦你使用執行個體方法,就必須執行個體化該對象,靜態方法則不同,後者可以在任何時候被調用。另外,你也瞭解了"this"引用是如何調用執行個體方法的。 

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。