Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
46m 57s
在本文中,我們將深入探討C#的存取修飾字,它們定義了C#中型別、方法和變數的可見性和可存取性。 Tim Corey在他的影片"C#存取修飾字(不止public和private)—— 它們是什麼,怎麼用,以及最佳實踐"中,解釋了各種存取修飾字並展示了它們在控制台應用程式中的實際用法。
本文將解釋Tim所涵蓋的內容,並提供程式碼範例以加深您的理解。 所提供的時間標記使您可以跟隨影片進行更具有實際動手操作的體驗。
Tim Corey首先介紹了存取修飾字,解釋它們決定了在C#中誰可以看到和使用資源。 雖然我們熟悉常用的public和private修飾字,但Tim探討了六種不同的存取修飾字及其使用案例。
Tim設置了一個簡單的應用程式來演示各種存取修飾字的工作原理。 該應用程式由一個控制台使用者介面和一個示範程式庫組成,兩者都在.NET框架中。
public class AccessDemo
{
private void PrivateDemo() { }
internal void InternalDemo() { }
public void PublicDemo() { }
}Public Class AccessDemo
Private Sub PrivateDemo()
End Sub
Friend Sub InternalDemo()
End Sub
Public Sub PublicDemo()
End Sub
End Class私有修飾字限制方法、字段或屬性的存取僅限於其定義的類別內。
public class AccessDemo
{
private void PrivateDemo()
{
Console.WriteLine("Private method can only be accessed within this class.");
}
public void CallPrivateDemo()
{
PrivateDemo(); // Works because it's within the same class
}
}Public Class AccessDemo
Private Sub PrivateDemo()
Console.WriteLine("Private method can only be accessed within this class.")
End Sub
Public Sub CallPrivateDemo()
PrivateDemo() ' Works because it's within the same class
End Sub
End Class解釋:PrivateDemo 方法只能在 AccessDemo 類中存取。 在影片中,Tim演示了它無法從類別外部存取,即使其他類別在同一個專案中。
最佳實踐:當您希望限制存取類別的內部運作,以確保其不能被應用程式的其他部分直接更改時,請使用私有。
內部修飾字允許方法或屬性僅在同一個元件(專案)內存取。 這比私有存取修飾字更廣泛,因為它包括所有同一個專案中的類別。
public class AccessDemo
{
internal void InternalDemo()
{
Console.WriteLine("Internal method is accessible within the same assembly.");
}
}Public Class AccessDemo
Friend Sub InternalDemo()
Console.WriteLine("Internal method is accessible within the same assembly.")
End Sub
End Class解釋:InternalDemo 方法可以被同一個元件中的任何類別存取,但不能從其他元件存取。 在影片中,Tim展示了內部修飾字允許內部專案中存取,但拒絕來自外部的存取。
最佳實踐:當方法或屬性僅供當前元件使用時,請使用內部修飾字,如不應暴露給外部專案的輔助功能或實用工具。
公開修飾字允許從任何其他類別或元件存取方法或屬性。 這是最具開放性的存取級別。
public class AccessDemo
{
public void PublicDemo()
{
Console.WriteLine("Public method can be accessed from any class.");
}
}Public Class AccessDemo
Public Sub PublicDemo()
Console.WriteLine("Public method can be accessed from any class.")
End Sub
End Class解釋:PublicDemo 方法從任何地方均可存取,包括同一個元件或其他元件中的類別。 Tim示範了公開是最常見的存取修飾字,特別是在公開方法在庫中時。
最佳實踐:當方法或屬性需要由應用程式的其他部分或外部專案存取時,請使用公開修飾字,如API端點或廣泛使用的實用工具。
受保護修飾字允許在其定義的類別內以及任何派生類別(繼承)中存取方法或屬性。 此修飾字對於物件導向程式設計特別有用,特別是在繼承的情況下。
public class AccessDemo
{
protected void ProtectedDemo()
{
Console.WriteLine("Protected method can be accessed within the class and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedDemo()
{
ProtectedDemo(); // Accessible because of inheritance
}
}Public Class AccessDemo
Protected Sub ProtectedDemo()
Console.WriteLine("Protected method can be accessed within the class and derived classes.")
End Sub
End Class
Public Class DerivedClass
Inherits AccessDemo
Public Sub CallProtectedDemo()
ProtectedDemo() ' Accessible because of inheritance
End Sub
End Class解釋:ProtectedDemo 方法可以從 AccessDemo 類及其派生類中存取。 Tim解釋說,受保護雖然不常見,但在處理繼承時非常有用。
最佳實踐:當您希望允許派生類別存取特定的方法或屬性,但不希望它們被類別層階之外所存取時,請使用受保護修飾字。
私有受保護修飾字結合了私有和受保護的規則。 它限制方法或屬性在定義類和同一個元件中的派生類中存取。 這意味著它提供了更進一步的保護級別,並對繼承型存取控制設置了更緊密的邊界,與僅受保護相比。
public class AccessDemo
{
private protected void PrivateProtectedDemo()
{
Console.WriteLine("Private Protected method can be accessed within the same assembly and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallPrivateProtectedDemo()
{
PrivateProtectedDemo(); // Accessible because of inheritance within the same assembly
}
}
public class UnrelatedClass
{
public void TestAccess()
{
// PrivateProtectedDemo(); // Error: Not accessible in unrelated classes
}
}Public Class AccessDemo
Private Protected Sub PrivateProtectedDemo()
Console.WriteLine("Private Protected method can be accessed within the same assembly and derived classes.")
End Sub
End Class
Public Class DerivedClass
Inherits AccessDemo
Public Sub CallPrivateProtectedDemo()
PrivateProtectedDemo() ' Accessible because of inheritance within the same assembly
End Sub
End Class
Public Class UnrelatedClass
Public Sub TestAccess()
' PrivateProtectedDemo() ' Error: Not accessible in unrelated classes
End Sub
End Class解釋:PrivateProtectedDemo 方法可以在 DerivedClass 中存取,因為它繼承自 AccessDemo 並且存在於同一個元件中。 然而,它不能在 UnrelatedClass 中存取,因為這個類不繼承自 AccessDemo。
最佳實踐:當您需要緊密控制同一個元件內的繼承存取時,請謹慎使用私有受保護存取修飾字。 這在方法或屬性暴露於跨元件可能會損害封裝的情況中特別有用。
受保護內部修飾字結合了受保護和內部存取修飾字的級別。 它允許從同一個元件或派生類別中存取,即使它們位於不同的元件。
public class AccessDemo
{
protected internal void ProtectedInternalDemo()
{
Console.WriteLine("Protected Internal method can be accessed within the same assembly or from derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedInternalDemo()
{
ProtectedInternalDemo(); // Accessible due to inheritance
}
}Public Class AccessDemo
Protected Friend Sub ProtectedInternalDemo()
Console.WriteLine("Protected Internal method can be accessed within the same assembly or from derived classes.")
End Sub
End Class
Public Class DerivedClass
Inherits AccessDemo
Public Sub CallProtectedInternalDemo()
ProtectedInternalDemo() ' Accessible due to inheritance
End Sub
End Class解釋:ProtectedInternalDemo 方法可以在同一個元件內以及來自任何派生類中存取,不論它們在何元件中。
最佳實踐:當您希望將方法公開給派生類(其他元件中)和同一個元件中的類別,但不希望將其公開給每個人時,請使用受保護內部。
Tim Corey解釋了使用存取修飾字的重要性以及為什麼不應該將所有內容設為公開。 雖然將所有內容設為公開看起來方便,但這會帶來重大風險,包括資料洩漏、漏洞和開發中的混亂。 存取修飾字的存在是為了安全資訊、防止無意的公眾存取,並提供程式碼庫的清晰性。
Tim討論了為什麼敏感資訊,如社會安全號碼(SSN)或信用卡號碼,不應公開。 他展示了一個"壞類別"的範例,由於公開存取而導致資料暴露的情況:
壞的範例:
public class User
{
public string SSN; // Anyone can access and modify it directly
}Public Class User
Public SSN As String ' Anyone can access and modify it directly
End Class好的範例:
public class User
{
private string ssn;
public string GetMaskedSSN()
{
return "XXX-XX-" + ssn.Substring(ssn.Length - 4);
}
public void SetSSN(string value)
{
// Add validation if needed
ssn = value;
}
}Public Class User
Private ssn As String
Public Function GetMaskedSSN() As String
Return "XXX-XX-" & ssn.Substring(ssn.Length - 4)
End Function
Public Sub SetSSN(value As String)
' Add validation if needed
ssn = value
End Sub
End Class開始:35:11
Tim解釋說,私有方法有助於封裝不應直接存取的行為。 他使用了 DeleteUser 方法作為更大進程的一部分,例如員工離職。
壞的範例:
public class UserManager
{
public void DeleteUser(int userId)
{
// Deletes the user without considering related processes
}
}Public Class UserManager
Public Sub DeleteUser(userId As Integer)
' Deletes the user without considering related processes
End Sub
End Class好的範例:
public class UserManager
{
public void OffboardUser(int userId)
{
RevokeAccess(userId);
DeleteUser(userId); // Used privately as part of offboarding
}
private void DeleteUser(int userId)
{
// Internal logic to delete the user
}
private void RevokeAccess(int userId)
{
// Logic to revoke system access
}
}Public Class UserManager
Public Sub OffboardUser(userId As Integer)
RevokeAccess(userId)
DeleteUser(userId) ' Used privately as part of offboarding
End Sub
Private Sub DeleteUser(userId As Integer)
' Internal logic to delete the user
End Sub
Private Sub RevokeAccess(userId As Integer)
' Logic to revoke system access
End Sub
End Class存取修飾字通過確保資料在適當的驗證下設置或檢索來防止漏洞。 Tim用涉及 Age 屬性的範例來說明這一點。
壞的範例:
public class Person
{
public int Age; // Can be directly set to an invalid value
}Public Class Person
Public Age As Integer ' Can be directly set to an invalid value
End Class好的範例:
public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value < 0 || value > 120)
throw new ArgumentOutOfRangeException("Age must be between 0 and 120.");
age = value;
}
}
}Public Class Person
Private _age As Integer
Public Property Age As Integer
Get
Return _age
End Get
Set(value As Integer)
If value < 0 OrElse value > 120 Then
Throw New ArgumentOutOfRangeException("Age must be between 0 and 120.")
End If
_age = value
End Set
End Property
End Class適當使用的存取修飾字通過僅提供必要的曝光簡化了開發,從而避免混淆。 例如,在擁有數千個方法的應用程式中,只公開公開的那些以確保開發者只看到相關選項。
範例:
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}Public Class MathLibrary
Public Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
Public Function Subtract(a As Integer, b As Integer) As Integer
Return a - b
End Function
Private Sub LogCalculation(operation As String, result As Integer)
' Logging is internal and not exposed
End Sub
End Class對於大規模項目,Tim解釋了正確使用存取修飾字如何確保僅暴露庫的必要部分,從而降低使用該庫的開發者的認知負擔。
範例:
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}Public Class MathLibrary
Public Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
Public Function Subtract(a As Integer, b As Integer) As Integer
Return a - b
End Function
Private Sub LogCalculation(operation As String, result As Integer)
' Logging is internal and not exposed
End Sub
End Class通過正確地使用這些存取修飾字,您可以使您的工作和下一個人的工作更輕鬆。
Tim Corey提供了一份清晰而實用的指南來掌握C#存取修飾字,並展示了如何有效地使用它們來建立安全的、可維護的、專業的應用程式。 他詳細的解釋和真實世界的例子使這個話題對所有級別的開發者都很容易理解。
欲獲得更深入的見解並觀看這些概念的實際應用,一定要觀看Tim的完整影片,並探索他的頻道,以獲取有關C#及其他程式設計主題的寶貴內容。 這是任何認真提升開發技巧的人必訪之地!
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy