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

Posted

技术标签:

【中文标题】什么是 C# 访问修饰符,它们如何比较?有没有像样的视觉图? [关闭]【英文标题】:What are the C# Access Modifiers, and how do they compare? Is there a decent visual diagram? [closed] 【发布时间】:2016-03-15 02:28:58 【问题描述】:

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

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

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

【问题讨论】:

我的目的是改进在谷歌搜索中找到的答案。我找不到访问修饰符的良好视觉表示。 我认为下图在社区 wiki 中会很有用,因为我看到多个问题试图将两个访问修饰符相互比较。如果没有正确的问题,我无法提交 wiki 答案。 这绝不会放宽问题的质量标准。如果您想发布答案,您需要就主题问题提出质量问题。您要发布答案并不意味着该问题不需要遵守规则。 @Servy 这个问题违反了哪条规则?当我处理这个问题时,我有这些确切的问题,并且无法找到一个包罗万象的答案来解释访问修饰符,不仅用定义,而且用视觉和例子来解释。如果可以的话,我很乐意改进这个问题。 这个问题太宽泛了,并且在询问关于已经现成的信息的问题时,并没有表现出足够的研究努力。 【参考方案1】:

根据MSDN C# Reference:

在 C# 中有 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";
        
    

Assembly2

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

【讨论】:

@RonBeyer 感谢您的耐心等待。我明白你现在在说什么。我已经更新了图表。 这更清楚了,谢谢,我会删除我的 cmets。

以上是关于什么是 C# 访问修饰符,它们如何比较?有没有像样的视觉图? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C# 五大修饰符

C# 中修饰符的基础结构和行为

C#语言中的修饰符汇总

Visual C# 2010 Express:为新类指定默认访问修饰符?

c# 曾经面试题

C#关键字:访问修饰符