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
46分57秒
在本文中,我们将深入探讨 C# 访问修饰符,它定义了 C# 中类型、方法和变量的可见性和可访问性。 Tim Corey 在他的视频" C# 访问修饰符(超越 public 和 private)- 它们是什么、如何使用它们以及最佳实践"中解释了各种访问修饰符,并在控制台应用程序中演示了它们的实际用法。
本文将解释 Tim 所讲解的内容,并提供代码示例以加深您的理解。 提供的时间戳可让您跟随视频进行操作,从而获得更实际的体验。
Tim Corey 首先介绍了访问修饰符,并解释说它们决定了谁可以在 C# 中查看和使用资源。 虽然我们熟悉常用的公共和私有修饰符,但 Tim 探讨了六种不同的访问修饰符及其使用案例。
Tim 创建了一个简单的应用程序来演示各种访问修饰符的工作原理。 该应用程序由控制台用户界面和演示库组成,两者均采用 .NET Framework编写。
*控制台 UI :用于测试访问修饰符的控制台应用程序。 *演示库:一个用于演示不同访问修饰符的类库。
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 Classprivate 修饰符将方法、字段或属性的访问权限限制在定义它的类中。
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 演示了即使其他类在同一个项目中,也无法从类外部访问它。
最佳实践:当您想要限制对类的内部运作的访问时,请使用 private,以确保它不能从应用程序的其他部分直接更改。
内部修饰符仅允许在同一程序集(项目)内访问方法或属性。 这比私有访问修饰符的范围更广,因为它包括同一项目中的所有类。
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 展示了内部权限允许访问同一项目内部,但拒绝从外部访问。
最佳实践:对于仅供当前程序集内使用的方法或属性,例如不应向外部项目公开的辅助函数或实用程序,请使用 internal。
public 修饰符允许从任何其他类或程序集访问方法或属性。 这是权限最高的访问级别。
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 证明 public 是最常见的访问修饰符,尤其是在公开库中的方法时。
最佳实践:对于需要被应用程序其他部分或外部项目(例如 API 端点或广泛使用的实用程序)访问的方法和属性,请使用 public。
protected 修饰符允许访问定义该方法或属性的类中的方法或属性,以及任何派生类(继承)中的方法或属性。 该修饰符对面向对象编程非常有用,尤其是在继承的情况下。
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解释说,受保护的继承方式虽然不太常见,但在处理继承问题时非常有用。
最佳实践:当您希望允许派生类访问特定方法或属性,但不希望它们在类层次结构之外可访问时,请使用 protected。
私有受保护修饰符结合了私有和受保护的规则。 它限制对定义类和同一程序集中的派生类中的方法或属性的访问。 这意味着与受保护的访问控制相比,它提供了更高的保护级别和更严格的基于继承的访问控制边界。
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 方法可以从同一程序集内访问,也可以从任何派生类访问,无论该派生类所在的程序集。
最佳实践:当你想要将一个方法同时暴露给派生类(在其他程序集中)和同一程序集中的类,但又不想暴露给所有人时,请使用 protected internal。
Tim Corey 解释了使用访问修饰符的重要性,以及为什么不应该把所有内容都设为公开。 虽然将所有内容公开似乎很方便,但这会带来重大风险,包括数据泄露、漏洞和开发过程中的混乱。 访问修饰符的存在是为了保护信息安全、防止意外的公共访问,并使代码库更加清晰。
蒂姆讨论了为什么社会安全号码(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 ClassTim 解释说,对于大型项目,正确使用访问修饰符可以确保只公开库的必要部分,从而减轻使用该库的开发人员的认知负担。
示例:
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