1. C# 裡的主要存取修飾詞
寫程式的時候,常常會想要很明確地控制,誰 跟 從哪裡 可以看到或改你的變數、呼叫你的方法。這就像住大樓一樣:不是每個空間都對所有人開放。有些只有住戶能進,有些只有維修人員能進。
在程式裡這種「存取控制」就是靠 存取修飾詞 來搞定的。它們決定 class 的成員(變數、欄位、方法、屬性等等)能不能被 class 外面、別的 class、甚至別的專案看到。這也是 OOP 裡 封裝 的重點之一:我們把實作細節藏起來,只給外面需要的「介面」。
這邊有個表格,列出主要的修飾詞跟簡單說明:
| 修飾詞 | 哪裡看得到?(白話) |
|---|---|
|
到處都看得到(專案內外都行,只要有組件) |
|
只有同一個 class 裡面看得到 |
|
跟 private 一樣 |
看起來很可怕?其實沒什麼難的,來看幾個例子就懂了,哪裡該用哪個。
2. public 修飾詞 — 誰都能來
public 這個修飾詞會讓你的變數或方法 到處都看得到。如果你把 class 的成員宣告成 public,任何看到你這個 class 的程式碼都能用它。
public class Person
{
public string Name;
public void SayHello()
{
Console.WriteLine($"哈囉!我叫 {Name}");
}
}
現在不管在哪裡(同一個專案或其他專案,只要有加組件參考),都可以寫:
Person p = new Person();
p.Name = "艾莉絲";
p.SayHello();
實用建議:不要什麼都設 public,這樣你的程式安全性會很糟。
3. private 修飾詞 — 這是私人財產!
private 會把 class 裡的東西藏起來:外面完全看不到、也不能改。預設情況下 C# 的欄位和方法都是 private,除非你自己寫別的修飾詞。
public class Cup
{
private double volume; // 只有 Cup 這個 class 自己看得到這個欄位
public void Fill(double value)
{
volume = value; // 可以在 class 裡用
}
public double GetVolume()
{
return volume; // 但外面的人完全不知道有 volume 這東西
}
}
這裡 volume 對其他人來說是隱藏的,但 Cup 裡的任何方法都能用它。要讓外面知道容量,我們提供一個公開方法 GetVolume()。
4. 作用域:變數、方法和 class
作用域 就是你在程式裡哪裡可以用某個名字(變數、方法、class)。
- 區域變數(在方法或區塊裡宣告):只在那個方法或區塊裡看得到。
- 方法參數:只在那個方法裡看得到。
- class 欄位:在整個 class 裡都看得到(還是要看修飾詞)。
- class:巢狀 class 如果是 private,只有外層 class 看得到,等等。
來看個作用域的例子:
public class Counter
{
private int count = 0; // 在整個 class 裡都看得到
public void Increment()
{
count++; // 可以用欄位
int temp = count * 2; // temp 只在 Increment 裡看得到
}
public int GetCount()
{
// 這裡看不到 temp!
return count;
}
}
如果你想在 GetCount() 裡用 temp,會直接噴錯。
5. 變數遮蔽(shadowing)
遮蔽 就是你在一個作用域裡宣告了一個跟外層同名的變數(或參數)。在這個區塊裡,「新的」名字就 遮蔽 了外層的,直接用不到外層的值。
遮蔽的例子:
class ShadowDemo
{
int value = 10; // class 欄位
void PrintValue()
{
Console.WriteLine(value); // 10 — class 欄位
int value = 5; // 區域變數遮蔽 class 欄位
Console.WriteLine(value); // 會印 5,不是 10
}
}
這個例子裡,當你寫 int value = 5;,這個 遮蔽 了 class 裡同名的欄位。在 PrintValue() 裡用 value,會用到區域變數,不是 class 欄位。
如果你真的要用 class 欄位,可以用 this 關鍵字:
class ShadowDemo
{
int value = 10;
void PrintValue()
{
Console.WriteLine(value); // 10 — class 欄位
int value = 5;
Console.WriteLine(value); // 5 — 區域變數
Console.WriteLine(this.value); // 10 — class 欄位
}
}
遮蔽很容易讓人搞混,所以建議變數名稱要有意義、不要重複,尤其是團隊開發的時候。
GO TO FULL VERSION