什么样的访问修饰符可以应用于一个类?

4
经过一番研究,我发现可以应用于类的唯一访问修饰符是:
  • public - 可在任何程序集中使用
  • internal - 仅限于当前程序集中使用
但下面的错误信息似乎暗示了如果一个类没有定义在命名空间中,它可以被定义为 privateprotected 或者 protected internal类的修饰符只有public和internal吗?还有其他的吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test2343434
{
    class Program
    {
        static void Main(string[] args)
        {
            Tools.ToolManager toolManager = new Tools.ToolManager();

            Console.ReadLine();
        }
    }

}

namespace Tools
{
    //error: Elements defined in a namespace cannot be explicitly 
    //declared as private, protected, or protected internal
    private class ToolManager 
    {
        public ToolManager()
        {
            Console.WriteLine("inside tool manager");
        }
    }
}
4个回答

8

嵌套类型可以声明为private、protected或protected internal。当然,你仍然可以将嵌套类型声明为public或internal - 只是当它们被嵌套时,你只能使用上述访问修饰符进行声明。

public class OuterClass
{
    private class PrivateNested {}
    protected class ProtectedNested {}
    protected internal class ProtectedInternalNested {}
    public class PublicNested {}
    internal class InternalNested {}
}

请注意,您无法将嵌套在struct中的类型声明为protectedprotected internal,因为这样做没有任何意义 :)
public struct OuterStruct
{
    private class PrivateNested {}
    public class PublicNested {}
    internal class InternalNested {}
}

C#不允许在接口中嵌套类型(可惜,在我看来很有用,可以用于代码契约)。

对于其他嵌套类型(枚举,结构体,接口,委托)也是如此。


值得了解的是,私有嵌套类可能非常有用。 - Dan Bryant
关键点是命名空间不是容器,而类是容器。可能的访问修饰符取决于它是否在容器中(例如,类是否为成员)。 - Stephen Cleary
@Stephen:命名空间是一种容器:非嵌套类型是命名空间的成员。根据C#规范:“命名空间成员声明是命名空间声明(§9.2)或类型声明(§9.6)。” - Jon Skeet
@Jon:我的术语可能需要改进 - 所有好的名称都被占用了。 :) 关键是程序员经常陷入将命名空间视为静态类相似的陷阱中。我认为更正确的看法是,所有顶级类型都是平面的,并且命名空间只是用作名称前缀。一旦进行了这种心理调整,就会变得非常清晰明了,为什么顶级类型唯一可能的访问修饰符是public和internal。 - Stephen Cleary

3
请看这个MSDN页面

命名空间中的类型声明可以是public或internal。 如果没有指定访问级别,则默认为internal。

在命名空间中,将类型声明设置为除public和internal之外的任何其他访问级别都没有意义(C#不支持友元类或类似概念)。


3
答案可以在辅助级别中找到。
顶级类,即不嵌套在另一个类中的类,只能是public或internal。默认情况下(如果您没有声明任何内容),它是internal。
嵌套类可以具有所有五种可能的可访问性级别,即public、protected、internal、private、protected internal。

0
在这个问题的背景下,指出一个不太为人知的机制可能是有趣的,可以使internal类对其他程序集可见。该机制是InternalsVisibleTo属性。它并不被认为是任何访问修饰符之一,但确实具有操纵谁具有访问权限的效果。这个概念被称为友元程序集。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接