明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

C#圖文說(shuō)明教程第5課:方法

[摘要]本節(jié)課向你介紹C#的方法,其目的是:1.了解方法的結(jié)構(gòu)格式2.了解靜態(tài)和實(shí)例方法之間的區(qū)別3.學(xué)會(huì)實(shí)例對(duì)象的使用4.學(xué)會(huì)如何調(diào)用實(shí)例化的對(duì)象5.學(xué)會(huì)方法的四種參數(shù)類(lèi)型的使用6.學(xué)會(huì)使用"this"引用以往,對(duì)于每個(gè)程序來(lái)說(shuō),所有的工作都在Main()方法中實(shí)現(xiàn)。這對(duì)于功能簡(jiǎn)單的...
本節(jié)課向你介紹C#的方法,其目的是:
1.了解方法的結(jié)構(gòu)格式

2.了解靜態(tài)和實(shí)例方法之間的區(qū)別

3.學(xué)會(huì)實(shí)例對(duì)象的使用

4.學(xué)會(huì)如何調(diào)用實(shí)例化的對(duì)象

5.學(xué)會(huì)方法的四種參數(shù)類(lèi)型的使用

6.學(xué)會(huì)使用"this"引用

以往,對(duì)于每個(gè)程序來(lái)說(shuō),所有的工作都在Main()方法中實(shí)現(xiàn)。這對(duì)于功能簡(jiǎn)單的程序是合適的,因?yàn)閮H僅用來(lái)學(xué)習(xí)一些概念。有個(gè)更好的方法來(lái)組織你的程序,那就是使用方法。方法是很有用的,因?yàn)榉椒ǹ梢宰屇阍诓煌膯卧蟹珠_(kāi)設(shè)計(jì)你的邏輯模塊。

方法的結(jié)構(gòu)格式如下:

屬性 修飾符 返回值類(lèi)型 方法名(參數(shù)) { 語(yǔ)句 }

我們將在后面的課程中,討論屬性和修飾符。方法的返回值可以是任何一種C#的數(shù)據(jù)類(lèi)型,該返回值可以賦給變量,以便在程序的后面部分使用。方法名是唯一,可以被程序調(diào)用。為使得你的代碼變得更容易理解和記憶,方法的取名可以同所要進(jìn)行的操作聯(lián)系起來(lái)。你可以傳遞數(shù)據(jù)給方法,也可以從方法中返回?cái)?shù)據(jù)。它們由大括號(hào)包圍起來(lái)。大括號(hào)中的語(yǔ)句實(shí)現(xiàn)了方法的功能。

1.清單5-1. 一個(gè)簡(jiǎn)單的方法: 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;
}
}

說(shuō)明

1.清單5-1中的程序類(lèi)似于第四課中的DoLoop程序。

區(qū)別在于:前一課中的程序打印出菜單內(nèi)容,并在Main()方法中接受用戶(hù)的輸入,而本課中,該功能用一個(gè)名為getChoice()的方法實(shí)現(xiàn),該方法的返回值類(lèi)型是個(gè)字符串類(lèi)型。在main方法中,在switch語(yǔ)句中用到了該串。方法"getChoice"實(shí)現(xiàn)了調(diào)用時(shí)所完成的工作。方法名后面的括號(hào)內(nèi)是空的,因?yàn)檎{(diào)用getChoice()方法時(shí),不需要傳遞任何數(shù)據(jù)。

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

雖然它與 Main()方法中的"myChoice"變量同名同類(lèi)型, 但它們是不同的兩個(gè)變量,因?yàn)榫植孔兞績(jī)H僅在其定義的塊內(nèi)可見(jiàn)。換句話(huà)說(shuō), getChoice()方法中的"myChoice" 同Main()方法中的"myChoice"變量沒(méi)有絲毫聯(lián)系。getChoice()方法打印出一個(gè)菜單到控制臺(tái),并讀取用戶(hù)的輸入。"return" 語(yǔ)句把"myChoice"變量值返回給Main()方法中的調(diào)用者getChoice()。注意: "return"語(yǔ)句返回類(lèi)型同該方法中定義的返回值類(lèi)型相同,本例中,該返回值是個(gè)字符串。

3.在Main()方法中,在使用getChoice()之前,實(shí)例化了一個(gè)新的"OneMethod"對(duì)象。

這是因?yàn)椋何覀儧](méi)有指明一個(gè)"靜態(tài)"修飾符。(注意:Main()函數(shù)帶有"靜態(tài)"修飾符),getChoice()就成為一個(gè)實(shí)例的方法。 實(shí)例方法和靜態(tài)方法的區(qū)別是:前者可以創(chuàng)建多個(gè)類(lèi)的實(shí)例,每個(gè)實(shí)例有自己的單獨(dú)的getChoice()方法。而一旦方法是靜態(tài)的,就不存在方法的實(shí)例,你只能調(diào)用該靜態(tài)方法的一個(gè)實(shí)現(xiàn)。

所以,正如前面所講的,因?yàn)間etChoice()并不是靜態(tài)的,所以,我們必須實(shí)例化一個(gè)新對(duì)象來(lái)使用它。這是通過(guò)定義"OneMethod om = new OneMethod()"來(lái)進(jìn)行的。在等號(hào)的左邊,是對(duì)象引用"om",其類(lèi)型是OneMethod。"om"是個(gè)對(duì)象的引用,這點(diǎn)很重要,"om"并不是對(duì)象自身,它是個(gè)引用OneMethod類(lèi)型對(duì)象的變量。 在等號(hào)的右邊,把新創(chuàng)建的OneMethod對(duì)象賦給引用"om"。 關(guān)鍵字"new"是個(gè)在堆上創(chuàng)建對(duì)象的新實(shí)例的C#運(yùn)算符。此處完成的工作是: 在堆上創(chuàng)建一個(gè)新的OneMethod實(shí)例,并把它賦給om引用。一旦有了om引用的OneMethod對(duì)象實(shí)例,就可以通過(guò)om引用來(lái)對(duì)實(shí)例進(jìn)行處理。

方法,域和其他類(lèi)成員可以通過(guò)"." (點(diǎn))運(yùn)算符進(jìn)行訪(fǎng)問(wèn),標(biāo)識(shí)和操縱。一旦需要調(diào)用方法getChoice(),就通過(guò)om引用,并使用點(diǎn)運(yùn)算符"om.getChoice()"來(lái)進(jìn)行。 getChoice() 塊中的語(yǔ)句執(zhí)行完畢之后即返回。為了捕捉到getChoice()的返回值,我們使用了賦值運(yùn)算符"="。 返回串放到了Main()函數(shù)的局部變量 myChoice中,從那里,程序的其余部分按照前面課程中介紹的方式正常執(zhí)行。

2.清單5-2. 方法參數(shù):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);
}
}
}

說(shuō)明

1.清單5-2是清單5-1的修改,主要是對(duì)程序進(jìn)行了模塊化,并添加了更多的實(shí)現(xiàn),以便闡述參數(shù)傳遞的用法。

C#可以處理四種類(lèi)型的參數(shù):out(輸出),ref(引用),params(數(shù)組)和value(值)。為了說(shuō)明參數(shù)的用法,我們用兩個(gè)字符串域創(chuàng)建地址類(lèi)。

2.在Main()方法中,我們調(diào)用getChoice()來(lái)讀取用戶(hù)的輸入,并且把字符串放到myChoice變量中。

之后,把myChoice變量作為makeDecision()函數(shù)的實(shí)在參數(shù)。在實(shí)現(xiàn)makeDecision()方法時(shí),注意其形式參數(shù)為字符串myChoice。需要再次說(shuō)明的是:這是個(gè)新的myChoice變量,不同于調(diào)用者的實(shí)在參數(shù),僅僅是適用于本方法的局部變量。 因?yàn)閙akeDecision()方法的myChoice參數(shù)沒(méi)有任何其他修飾符,故認(rèn)為它是"值"參,即實(shí)在參數(shù)的值被拷貝到棧中,故作為值參的變量是局部的,任何對(duì)局部變量值的改變并不影響到調(diào)用者的實(shí)在參數(shù)的值。換句話(huà)說(shuō),值參僅僅是來(lái)自調(diào)用者的輸入。

3.makeDecision()方法中的switch語(yǔ)句完成如下功能:

在每種情形下,都調(diào)用相應(yīng)的方法。這些方法的調(diào)用不同于Main()方法。除了使用"mp" 引用,它們還使用了"this"關(guān)鍵字。"this"是對(duì)當(dāng)前對(duì)象的引用。由于makeDecision()方法不是靜態(tài)方法,當(dāng)前對(duì)象已經(jīng)被實(shí)例化,所以可以使用"this"引用來(lái)調(diào)用同一實(shí)例中的方法。

4.addAddress()方法用到了"ref"參數(shù),即引用可作為參數(shù)來(lái)傳遞,即該引用被拷貝到棧中,其引用的對(duì)象同調(diào)用者的實(shí)參所引用的對(duì)象是同一個(gè)。

這意味著:任何對(duì)局部引用的對(duì)象的改變也就是對(duì)調(diào)用者所引用的對(duì)象的改變。你可以想象一下,這就相當(dāng)于輸入/輸出參數(shù)。

5.modifyAddress()中有一個(gè)輸出參數(shù)。

輸出參數(shù)僅僅傳遞給被調(diào)用函數(shù)。一旦調(diào)用該方法時(shí),在棧中的僅有的一個(gè)引用未被賦值,因?yàn)楦鶕?jù)賦值的確定性原則,在該變量沒(méi)有被賦值之前,就不能使用該變量。modifyAddress()方法的第一行作為注釋?zhuān)f(shuō)明了這一點(diǎn)。你可以試著去掉注釋符,編譯一下程序,看看結(jié)果如何。一旦該變量被賦了值,在程序返回之后,輸出參數(shù)就被拷貝到調(diào)用者的參數(shù)中。所以,在方法返回之前,必須給輸出參數(shù)賦值。

小結(jié)
C# 語(yǔ)言的一個(gè)很有用途的參數(shù)類(lèi)型是數(shù)組參數(shù),它須是一維或多維的數(shù)組。在makeDecision()方法中,我們傳遞了用四個(gè)逗號(hào)隔開(kāi)的字符串參數(shù)。參數(shù)的個(gè)數(shù)是變量。在viewAddresses()方法中,使用了foreach循環(huán),逐一輸出這些字符串。數(shù)組參數(shù)僅是一種輸入性質(zhì)的參數(shù),任何對(duì)數(shù)組參數(shù)值的改變僅僅影響到局部的副本值。

概括地講,你現(xiàn)在已經(jīng)理解了方法的組織結(jié)構(gòu)。你還了解了方法的實(shí)現(xiàn)可以采用的四種參數(shù)類(lèi)型及其格式。 一旦你使用實(shí)例方法,就必須實(shí)例化該對(duì)象,靜態(tài)方法則不同,后者可以在任何時(shí)候被調(diào)用。另外,你也了解了"this"引用是如何調(diào)用實(shí)例