跳至页脚内容
Iron Academy Logo
学习 C#
学习 C#

其他类别

了解 C# 访问修饰符

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 void PrivateDemo() { }
    internal void InternalDemo() { }
    public void PublicDemo() { }
}

1. 私人

它是什么:

private 修饰符将方法、字段或属性的访问权限限制在定义它的类中。

代码示例:

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 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
    }
}

解释AccessDemo类内可访问。 在视频中,Tim 演示了即使其他类在同一个项目中,也无法从类外部访问它。

最佳实践:当您想要限制对类的内部运作的访问时,请使用 private,以确保它不能从应用程序的其他部分直接更改。

2. 内部

它是什么:

内部修饰符仅允许在同一程序集(项目)内访问方法或属性。 这比私有访问修饰符的范围更广,因为它包括同一项目中的所有类。

代码示例:

public class AccessDemo
{
    internal void InternalDemo()
    {
        Console.WriteLine("Internal method is accessible within the same assembly.");
    }
}
public class AccessDemo
{
    internal void InternalDemo()
    {
        Console.WriteLine("Internal method is accessible within the same assembly.");
    }
}

解释InternalDemo方法可以被同一程序集内的任何类访问,但其他程序集不可访问。 在视频中,Tim 展示了内部权限允许访问同一项目内部,但拒绝从外部访问。

最佳实践:对于仅供当前程序集内使用的方法或属性,例如不应向外部项目公开的辅助函数或实用程序,请使用 internal。

3. 公众

它是什么:

public 修饰符允许从任何其他类或程序集访问方法或属性。 这是权限最高的访问级别。

代码示例:

public class AccessDemo
{
    public void PublicDemo()
    {
        Console.WriteLine("Public method can be accessed from any class.");
    }
}
public class AccessDemo
{
    public void PublicDemo()
    {
        Console.WriteLine("Public method can be accessed from any class.");
    }
}

解释PublicDemo方法从任何地方都可访问,包括同一程序集中的其他类或其他程序集。 Tim 证明 public 是最常见的访问修饰符,尤其是在公开库中的方法时。

最佳实践:对于需要被应用程序其他部分或外部项目(例如 API 端点或广泛使用的实用程序)访问的方法和属性,请使用 public。

4. 受保护的

它是什么:

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 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
    }
}

解释AccessDemo类及其任何继承类中访问。 Tim解释说,受保护的继承方式虽然不太常见,但在处理继承问题时非常有用。

最佳实践:当您希望允许派生类访问特定方法或属性,但不希望它们在类层次结构之外可访问时,请使用 protected。

5. 私人保护

它是什么:

私有受保护修饰符结合了私有和受保护的规则。 它限制对定义类和同一程序集中的派生类中的方法或属性的访问。 这意味着与受保护的访问控制相比,它提供了更高的保护级别和更严格的基于继承的访问控制边界。

代码示例:

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 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
    }
}

解释:由于继承自DerivedClass中是可访问的。 然而,它在AccessDemo

最佳实践:当需要严格控制同一程序集中的继承访问时,应谨慎使用私有受保护访问修饰符。 这在跨程序集公开方法或属性可能会破坏封装性的场景中尤其有用。

6. 受保护的内部

它是什么:

受保护的内部修饰符结合了受保护和内部访问修饰符级别。 它允许从同一个程序集或派生类进行访问,即使它们位于另一个程序集中。

代码示例:

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 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
    }
}

解释ProtectedInternalDemo方法可以在同一程序集内访问,也可以从任何派生类访问,而不论程序集。

最佳实践:当你想要将一个方法同时暴露给派生类(在其他程序集中)和同一程序集中的类,但又不想暴露给所有人时,请使用 protected internal。

为什么不把所有事情都公开呢?

Tim Corey 解释了使用访问修饰符的重要性,以及为什么不应该把所有内容都设为公开。 虽然将所有内容公开似乎很方便,但这会带来重大风险,包括数据泄露、漏洞和开发过程中的混乱。 访问修饰符的存在是为了保护信息安全、防止意外的公共访问,并使代码库更加清晰。

1. 保护隐私信息

蒂姆讨论了为什么社会安全号码(SSN)或信用卡号码等敏感信息不应该被公开。 他举例说明了"不良案例",即由于公共访问而导致数据泄露:

反例:

public class User
{
    public string SSN; // Anyone can access and modify it directly
}
public class User
{
    public string SSN; // Anyone can access and modify it directly
}

好例子:

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 string ssn;

    public string GetMaskedSSN()
    {
        return "XXX-XX-" + ssn.Substring(ssn.Length - 4);
    }

    public void SetSSN(string value)
    {
        // Add validation if needed
        ssn = value;
    }
}

2. 保护私有方法

开始时间:35:11 Tim解释说,私有方法有助于封装不应该直接访问的行为。 他使用DeleteUser方法作为更大过程的一部分,例如员工离职。

反例:

public class UserManager
{
    public void DeleteUser(int userId)
    {
        // Deletes the user without considering related processes
    }
}
public class UserManager
{
    public void DeleteUser(int userId)
    {
        // Deletes the user without considering related processes
    }
}

好例子:

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 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
    }
}

3. 防止漏洞

访问修饰符通过确保数据经过适当的验证来设置或检索,从而防止出现错误。 Tim 用包含Age属性的示例来说明这一点。

反例:

public class Person
{
    public int Age; // Can be directly set to an invalid value
}
public class Person
{
    public int Age; // Can be directly set to an invalid value
}

好例子:

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 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;
        }
    }
}

4. 减少困惑,增强清晰度

正确使用访问修饰符可以简化开发,因为它只公开必要的内容,避免混淆。 例如,在一个拥有数千个方法的应用程序中,只公开方法可以确保开发人员只看到相关的选项。

示例:

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 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
    }
}

5. 在大型应用程序或库中的优势

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 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
    }
}

正确使用这些访问修饰符,可以让你的工作和下一个人的工作变得更轻松。

结论

Tim Corey 提供了一份清晰实用的指南,指导读者掌握 C# 访问修饰符,并展示了如何有效地使用它们来创建安全、可维护和专业的应用程序。 他详尽的解释和真实案例使各个级别的开发人员都能理解这个主题。

想要更深入地了解这些概念并了解它们的实际应用,请务必观看 Tim 的完整视频,并浏览他的频道,获取有关 C# 和其他编程主题的宝贵内容。 对于任何认真想要提高开发技能的人来说,这都是一个必看的资源!

Hero Worlddot related to 了解 C# 访问修饰符
Hero Affiliate related to 了解 C# 访问修饰符

分享您的所爱,赚取更多收入

您为使用 .NET、C#、Java、Python 或 Node.js 的开发人员创建内容吗?将您的专业知识转化为额外收入!

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我