了解 C# 中 类 的访问说明符

Understanding Access specifiers on Classes in C#

首先,让我先说我理解访问说明符,只是看不到在 classes 中使用它们的意义。在方法上限制它们的范围是有意义的,但在 classes 上,你为什么要私有 class,难道 classes 的目的不是为了能够重用它们吗?

在 C# 中声明 class 时访问说明符的用途是什么?你会在什么时候使用它们?

谢谢

我会给你一个内部的例子class。想象一下我有一些 DLL。在这个 DLL 中,我只想公开一个名为 A 的 class。然而,这个 class A 应该可以访问 DLL 中的其他 classes - 因此我将在 DLL 内部制作所有其他 classes。因此,从 DLL 中您只能使用 class A,而 A 仍然可以访问 DLL 中的其他 classes - 但是您不能。

好吧,假设您希望 class 只能在她自己的程序集中访问:

internal class Test

假设您有两个 classes,一个在另一个里面(嵌套 classes):

protected internal class TestA
{
    private TestB _testB;

    private class TestB
    {
    }

    public TestA()
    {
        _testB = new TestB();
    }
}

TestB class 只能在 methods/properties/contructors 内部访问,在 TestA 内部或她自己内部。

这同样适用于 protected 修饰符。

//注

如果您不指定访问修饰符,默认情况下它将是 private,因此在我的示例中为以下行:

private TestB _testB;

等于

TestB _testB;

同样适用于class。

特殊修改器

然后,protected internal 连接两个修饰符,因此您只能在同一程序集 中访问 class 来自 class 即使它不在同一个程序集中,它也是由此派生的。示例:

程序集 1:

public class TestA : TestB
{
    public TestB GetBase()
    {
        return (TestB)this;
    }

    public int GetA1()
    {
        return this.a1;
    }
}
protected internal class TestB
{
    public int a1 = 0;
}

计划

TestA _testA = new TestA(); // OK
TestB _testB = new TestB(); // ERROR

int debugA = new TestA().a1 // ERROR
int debugB = new TestA().GetA1(); // OK

TestB testB_ = new TestA().GetBase(); // ERROR

来源

Link (Access Modifiers)

The type or member can be accessed by any code in the same assembly, but not from another assembly.

The type or member can be accessed only by code in the same class or struct.

The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.

The type or member can be accessed by any other code in the same assembly or another assembly that references it.

使用访问说明符的最大好处是当其他人正在使用您的 类 时。通过明确指定在您的对象中什么应该和什么不应该被触及,您可以保护您的对象内部机制和完整性不被滥用或损坏。

使用更大的 类,如果你把所有东西都做了 public,你也会让你的代码的用户更难使用 IntelliSense,这在你处理时非常方便带有未知库。

我创建了一个应用程序来理解访问说明符。

It will be more easy to understand it with code instead of Theory.

I have added my notes in code, for better guidance.

namespace ConsoleApplication1
{
    //A normal public class which contains all different types of access-modifier classes in the assembly named 'ConsoleApplication1'
    public class Base
    {
        public class PublicBase
        {
            public static void fn_PublicBase()
            {
                Console.WriteLine("fn_PublicBase");
            }
        }
        private class PrivateBase
        {
            public static void fn_PrivateBase()
            {
                Console.WriteLine("fn_PrivateBase");
            }
        }

        protected class ProtectedBase
        {
            public static void fn_ProtectedBase()
            {
                Console.WriteLine("fn_ProtectedBase");
            }
        }

        internal class InternalBase
        {
            public static void fn_InternalBase()
            {
                Console.WriteLine("fn_InternalBase");
            }
        }

        protected internal class ProInternalBase
        {
            public static void fn_ProInternalBase()
            {
                Console.WriteLine("fn_ProInternalBase");
            }
        }       

        //TIP 1:This class is inside the same class 'Base' so everything is accessible from above.Hurray!!
        class Base_Inside
        {
            public static void fn_Base_Inside()
            {
                //All methods are easily accessible.Does not consider a modified indeed.
                PublicBase.fn_PublicBase();
                PrivateBase.fn_PrivateBase();
                ProtectedBase.fn_ProtectedBase();
                InternalBase.fn_InternalBase();
                ProInternalBase.fn_ProInternalBase();
            }
        }
    }

    //Different class but inside the same assembly named 'ConsoleApplication1'
    public class Base_Sibling  : Base
    {        
        //TIP 2:This class is NOT in same class 'Base' but in the same assembly so  only protected is NOT accessible rest all are accessible.        
        public void fn_Base_Sibling()
        {
            PublicBase.fn_PublicBase();
            //PrivateBase.fn_PrivateBase();     //ERROR:Accesibility of 'protected'            
            ProtectedBase.fn_ProtectedBase();   //protected is accessible because Base_Sibling inherit class 'Base'. you can not access it via Base.ProtectedBase
            InternalBase.fn_InternalBase();
            ProInternalBase.fn_ProInternalBase();
        }
    }
}

Now to Understand difference between internal, protected internal, I Have added one for project named with Assembly_1 in same solution.

我继承了 ConsoleApplication1Base class 到 Derived class Assembly_1.

namespace Assembly_1
{
    //TIP:if it does not inherit class 'ConsoleApplication1.Base' then we can not access any thing beacuse this is different assembly.
    //TIP:only INTERNAL is NOT accessible , rest all are accessible from first assembly if it inherits class 'Soul'
    public class Derived : ConsoleApplication1.Base
    {
        public class PublicDerived
        {
            public static void fn_PublicDerived()
            {
                PublicBase.fn_PublicBase();             //YES, becuase this is 'public'
              //PrivateBase.fn_PrivateBase();           //No, becuase this is 'private'
                ProtectedBase.fn_ProtectedBase();       //YES, becuase this is 'protected'
              //InternalBase.fn_InternalBase();         //No, becuase this is 'internal'
                ProInternalBase.fn_ProInternalBase();   //YES, becuase this is 'protected internal'
            }
        }
    }
}

- 更新答案 2019 -

您好,您可以通过下方找到辅助功能table