什么是 C# 访问修饰符,它们如何比较?有没有像样的视觉图?

Bri*_*ino -6 c# access-modifiers

研究:我已经阅读了MSDN C# Access Modifiers 参考,它提供了定义,但例子很少。这些定义是正确的,但如果在图表中直观地呈现它们会更容易理解。搜索 SO 我发现了几个问题,讨论了使用修饰符的特殊情况,或者将一个修饰符与另一个进行比较,但不是所有的修饰符,也不是视觉上的。我还在网上搜索了“C# Access Modifier Diagrams”并找到了这个快速参考,其中包含一些示例和图表,但并不像我希望的那样清晰。我无法找到此信息的多合一来源。

问题 我想找到 C# 访问修饰符的多合一指南,该指南使用定义、代码示例和可视化辅助工具(例如图表)显示以下内容。

  • C# 中有哪些不同的访问修饰符?
  • 每个修饰符的范围是什么,它们如何比较?
  • 它们如何应用于内部类、外部类、继承类和非继承类?

Bri*_*ino 5

根据MSDN C# 参考

在 C# 中有 5 个级别的访问修饰符。从限制最多到最少,它们如下所示:

  1. 私人的
    • 访问仅限于包含类型。
  2. 受保护
    • 访问仅限于包含类或从包含类派生的类型。
  3. 内部的
    • 访问仅限于当前程序集。
  4. 受保护的内部
    • 访问仅限于从包含类派生的当前程序集或类型。
  5. 民众
    • 访问不受限制。

我创建了下图来直观地显示这些修饰符的范围,因为它会影响多个程序集、类和派生类。

在此图中,有 5 个不同颜色的访问修饰符分组。对于每个分组,如果 BaseClassMember 或 NestedClass 使用相应的访问修饰符进行了修改,则只有该组内的类才能访问它。外面的课没有。

例如,如果 BaseClassMember 被修改为“Protected”,那么只有橙色 Protected 组中的类可以访问 BaseClassMember 。这些类是 BaseClass、InternalInheritedClass 和 ExternalInheritedClass。此行之外的类无权访问 BaseClassMember。

访问修饰符图 测试代码

装配 1

namespace Assembly1
{
    public class BaseClass
    {
        public int PublicMember;
        protected internal int ProtectedInternalMember;
        internal int InternalMember;
        protected int ProtectedMember;
        private int PrivateMember;

        public class PublicClass { }
        protected internal class ProtectedInternalClass { }
        internal class InternalClass { }
        protected class ProtectedClass { }
        private class PrivateClass { }
    }

    public class InternalClass
    {
        public InternalClass()
        {
            BaseClass class0Instance = new BaseClass();
            var publicMember = class0Instance.PublicMember;
            var protectedInternalMember = class0Instance.ProtectedInternalMember;
            var internalMember = class0Instance.InternalMember;
            var protectedMember = "not accessible";
            var privateMember = "not accessible";

            var publicClass = new BaseClass.PublicClass();
            var protectedInternalClass = new BaseClass.ProtectedInternalClass();
            var internalClass = new BaseClass.InternalClass();
            var protectedClass = "not accessible";
            var privateClass = "not accessible";
        }
    }

    public class InternalInheritedClass : BaseClass
    {
        public InternalInheritedClass()
        {
            var publicMember = this.PublicMember;
            var protectedInternalMember = this.ProtectedInternalMember;
            var internalMember = this.InternalMember;
            var protectedMember = this.ProtectedMember;
            var privateMember = "not accessible";

            var publicClass = new BaseClass.PublicClass();
            var protectedInternalClass = new BaseClass.ProtectedInternalClass();
            var internalClass = new BaseClass.InternalClass();
            var protectedClass = new BaseClass.ProtectedClass();
            var privateClass = "not accessible";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

装配2

using Assembly1;
namespace Assembly2
{
    public class ExternalClass
    {
        public ExternalClass()
        {
            BaseClass class0Instance = new BaseClass();
            var publicMember = class0Instance.PublicMember;
            var protectedInternalMember = "not accessible";
            var internalMember = "not accessible";
            var protectedMember = "not accessible";
            var privateMember = "not accessible";

            var publicClass = new BaseClass.PublicClass();
            var protectedInternalClass = "not accessible";
            var internalClass = "not accessible";
            var protectedClass = "not accessible";
            var privateClass = "not accessible";
        }
    }

    public class ExternalInheritedClass : BaseClass
    {
        public ExternalInheritedClass()
        {
            var publicMember = this.PublicMember;
            var protectedInternalMember = this.ProtectedInternalMember;
            var internalMember = "not accessible";
            var protectedMember = this.ProtectedMember;
            var privateMember = "not accessible";

            var publicClass = new BaseClass.PublicClass();
            var protectedInternalClass = new BaseClass.ProtectedInternalClass();
            var internalClass = "not accessible";
            var protectedClass = new BaseClass.ProtectedClass();
            var privateClass = "not accessible";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)