不學 JAVA 換學 C# 之覺得心累 - L1:ch7 方法
前言
方法 (Method) 是一組封裝的程式碼,用於執行特定的任務或邏輯。C# 中的方法具有靈活性和可重用性,使得程式更易於管理和維護。
特點:
- 可以有任意數量的參數與回傳值。
 - 內部的實作對外部是隱藏的,僅提供接口給使用者呼叫。
 - 可以重複使用,避免程式碼冗長與重複。
 
基本結構
每個方法都包含以下幾個部分:
- 存取修飾詞 (Accessibility Modifier):決定方法的存取範圍,例:
public或private。 - 靜態修飾詞 (Static Modifier):標記方法是靜態方法,或是需要實例化物件才能使用。
 - 回傳型態 (Return Type):指定方法的回傳值類型。如果不需要回傳值,使用 
void。如果需要有回傳值,除了指定回傳型態,方法內還需要用return回傳數值,且數值的型態必須跟定義的回傳型態一致。 - 方法名稱 (Method Name):方法的名稱。
 - 參數列表 (Parameter List):接收外部傳入的參數,參數間用逗號分隔。參數型態必須明確列出,例如 
int、string,以確保方法簽章的清晰性和正確性。 - 方法體 (Body):封裝的程式碼邏輯區塊。
 
1  | // 存取修飾詞:public, 回傳型態:int, 方法名稱:Add, 參數列表:(int x, int y)  | 
簽章 (Signature)
通常指方法的名稱、參數的型態、個數與順序,以及回傳值的型態。
它可以視為方法的唯一標識,用來區分不同的方法。例如,具有相同名稱但參數型態、個數與順序不同的方法會被視為不同的方法,這被稱為多載 (Overloading)。
使用、呼叫方法
1  | 方法名稱(傳入的參數列表);  | 
呼叫時
- 傳入的參數的數量與類型需要與定義方法時的簽章一致。
 - 需要保留回傳值時,指派給某個變數。
 
範例
1  | // 定義方法  | 
- 呼叫方法:
Add(1, 2)是對Add方法的一次呼叫。1和2是我們提供給Add方法的實際參數 (Arguments)。方法內部的x和y是對應的形式參數 (Parameters),它們分別接收1和2的值。方法執行時,會將這兩個數字相加,指派給變數total,然後回傳total的值。total的型態必須是int,因為必須跟 line 2 定義的回傳型態一致。 - 回傳值指派給某個變數:
Add方法的回傳型態是int,所以它會將計算結果total的值,也就是3回傳給呼叫它的程式碼。這裡的return total;將計算結果回傳,而 line 9 將回傳結果指派給int sum。 
存取修飾詞
類別 (class) 成員有方法 (method)、屬性 (property) 或欄位 (field)。而存取修飾詞是用來控制類別成員的可見性和存取範圍。目前先知道 public 和 private 就好。
public 修飾詞
使用 public 宣告的成員可以在程式的任何地方被存取,無論是同一個類別內、還是不同類別,甚至不同的命名空間。因此,需要讓其他類別或外部程式使用該成員時,就用 public。
private 修飾詞
使用 private 宣告的成員只能在同一個類別內存取,其他類別無法直接使用。因此,該成員只用於內部邏輯,而不需要對外暴露時,就用 private。
靜態修飾詞
靜態修飾詞和類別 class 有密切的關係,如果暫時看不懂,了解完類別再回來這看。
如果方法跟各別物件實例沒有關係,就用靜態方法,否則用非靜態方法。
非靜態方法
非靜態方法屬於物件,必須透過實例化物件來呼叫。使用物件名稱呼叫。
1  | 物件名稱.方法名();  | 
以下方例子來說,不同的實例化物件 Person 有不同的名字。印出名字 PrintName 這個方法就會跟各別物件有關係,所以必須使用非靜態方法。
1  | public class Person  | 
靜態方法
靜態方法屬於類別本身,不需實例化物件即可呼叫。適合用於不依賴於物件狀態的邏輯。使用類別名稱呼叫。
1  | 類別名稱.方法名();  | 
特性
- 靜態方法使用類別名稱後大家都可以呼叫,例:
Math.Max(x, y),Math是 C# 內建類別,Max是方法名。 - 靜態方法內部無法存取非靜態成員,因為非靜態成員需要具體的物件實例。
 
以下方例子來說,Max 方法不會依賴於不同的 Math 物件實例,直接用 Math 類別名呼叫 Max 方法。
1  | // 使用 Math 類別名稱呼叫 Max  | 
回傳型態和參數
無參數、無回傳值
僅執行動作而無需處理輸入或回傳結果。
1  | public void SayHello()  | 
有參數
適合需要輸入資料才能執行邏輯的情況。
1  | public void PrintMessage(string message)  | 
有回傳值
適合需要將處理結果回傳給呼叫者的情況。
1  | public int Multiply(int x, int y)  | 
陣列作為參數
在 C# 中,陣列作為參數傳遞時,是以複製記憶體位址的方式傳遞,但是因為實際參數 (Arguments) 和形式參數 (Parameters) 的值一樣,都是同一個記憶體位址,都指向同一個變數,這表示方法中對陣列內容的修改會影響到原始陣列,但重新指派陣列不會影響原始陣列,因為儲存的記憶體位址不一樣了。
C# 中沒有 Call/Pass by Address 這種說法,但是實際上 C# 的「陣列作為參數傳遞」就是 Call/Pass by Address,以下方的例子來說,是 copy 實際參數 arr 的位址給形式參數 numbers,而不是 Call/Pass by Reference 取別名。請參考:值 (value)、指標 (pointer/address)、參考 (reference)。取別名的話,重新指派陣列會影響原始陣列。
對陣列內容的修改會影響原始陣列
1  | public void ModifyArray(int[] numbers)  | 
重新指派陣列不會影響原始陣列
1  | public void ReassignArray(int[] numbers)  | 
注意:
- 原始資料的影響:由於陣列是傳址,對方法內的修改會直接反映在原始資料中。
 - 安全性考量:若不希望原始資料被修改,可以在傳入方法前複製陣列,避免直接影響原始資料。
 
1  | int[] copy = (int[])arr.Clone();  | 
Main 方法
在 C# 應用程式中,Main 方法是程式的入口點,負責啟動程式執行。它具有一些特別的特性和用法。
- 唯一性:每個 C# 應用程式只能有一個 
Main方法作為程式的入口點。 - 回傳型別:
void:不需要回傳值,適用於一般應用程式。int:可以回傳整數值,通常用於指示應用程式的執行狀態。- 0:約定俗成的成功碼,表示執行成功,程式正常結束。
 - 非 0 值:表示執行失敗或出現錯誤。
 
 - 參數:
string[] args:允許接收命令列參數,便於應用程式根據啟動時的參數執行不同邏輯。 - 靜態方法:
Main方法必須是static,因為它在沒有建立物件的情況下直接由執行環境呼叫。 - 多重定義:
Main方法可以有多個定義,但只有一個簽章會作為執行入口點。如果有多個定義,必須手動指定入口點。 
範例
基本架構
1  | using System;  | 
接收命令列參數
1  | using System;  | 
參考資料:
方法 (C# 程式設計手冊)
Main() 和命令列引數