关于c#:“private”和“protected Internal”有什么区别?

What is the difference between “private” and “protected Internal”?

我只想知道私有和受保护的内部访问说明符之间的实际区别。正如我所知道的

Visible to own class members: private and protected internal YES

Visible to object of other classes: Both NO

Visible to objects of other classes outside the namespace collection: Both NO

Visible to object of child classes outside the namespace collection: Both NO

如果private和protected internal做的一样,那么为什么我们需要两者都是足够的呢?


  • 当前程序集中或其他程序集中的派生类中的任何代码都可以看到protected internal成员。从技术上讲,它是protectedinternal的逻辑分离。
  • private成员仅对同一类中的代码可见。

protected internal实际上是仅次于public的第二大允许访问修改器。

值得注意的是,与internal相比,protected更为宽松,因为它允许从您无法控制的代码(即其他程序集)进行访问。虽然internal允许从当前程序集中的所有代码访问,但此代码是您的,您可以控制它!

换言之,protectedprotected internal成员是您的程序集的公共API的一部分(因此应记录在案)。internal成员不是。


图形概述(简而言之)

Visibility


private只对自己的类成员可见,而protected internal对子类以及命名空间集合内的其他类可见。


私有的

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

内部受保护

The type or member can be accessed by any code in the same assembly,
or by any derived class in another assembly


我试图通过阅读提供给不同论坛和博客的描述来理解.NET上下文中受保护的内部和内部之间的区别。我真的不明白,然后我用VS2015创建了两个单独的程序集。也许现在我有了基本的理解。我想和你分享,这可能对某人有帮助。我试图使用在一个程序集中声明的来自另一个程序集中的字段。我还尝试从另一个程序集中声明的类派生。这是程序集1中class1.cs的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
namespace Z_Dll_1
{
    public class PublicBaseClassAssemblyOne
    {
        internal int _myinternal = 200;
        protected internal int _protectedinternal = 100;
        protected int _myProtected = 123;
        private int _myPrivate = 2;
        public int _myPublic = 45;
    }

    public class DerivedClassAssemblyOne : PublicBaseClassAssemblyOne
    {
        protected internal int intM = 10;
    }

    internal class MyInternalClass
    {
        public void MyMethod()
        {
            Console.WriteLine("Method one with internal class");
            PublicBaseClassAssemblyOne cl1 = new PublicBaseClassAssemblyOne();
            cl1._myinternal = 1000; //Internal type is available since it is in same assembly
            cl1._protectedinternal = 10; // protected internal is available
            cl1._myPublic = 2;  // Public OK
            //cl1.myPrivate = ?? // nor available since it is private

            DerivedClassAssemblyOne drOne = new DerivedClassAssemblyOne();
            drOne._myinternal = 30; // Internal and available from derived class
            drOne._myPublic = 1; // Public
            drOne._protectedinternal = 2; // Able to be accessed from same assembly or derived class from other assembly
        }
    }
}

这是另一个程序集class2.cs的代码使用ZYDLLY1;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
namespace Z_Dll_2
{
    public class ClassAssembly2
    {
        public ClassAssembly2()
        {
            PublicBaseClassAssemblyOne classfromOtherAssembly = new PublicBaseClassAssemblyOne();
            classfromOtherAssembly._myPublic = 0; //Only public is available
        }
    }

    public class ClassDerivedFromOtherAssemblyClass : PublicBaseClassAssemblyOne
    {
        public ClassDerivedFromOtherAssemblyClass()
        {
        }
        void ClassDerivedFromOtherAssemblyClassTestMethod()
        {
            //_myinternal = 200; // can't access since it was internal to other assembly
            _protectedinternal = 100; // this can be accessed as it is  derived class from other class that has protected internal
            _myProtected = 123; // Ordinary protected data accessed from derived class
            //_myPrivate = 2; //Private member can't be accessed from  derived class
            _myPublic = 45; // Public can be accessed anyway

            //Try to create an instance of internal class
            //MyInternalClass intClass = new MyInternalClass(); //Not accessible from this assembly
        }
    }
}

实际上,我通常只对变量使用private,以确保它们不会被其他类误用。

但是,受保护的内部方法,我通常会用于我不希望大多数其他类能够使用的方法,但我希望能够访问这些方法来编写测试用例。它非常方便,因为它允许在健全的名称空间或包结构中创建测试类,然后可以访问这些受保护的内部方法,而不会不适当地将它们向世界其他地方打开。

这种方法确实需要一种编码方法,在这种方法中,编写容易"可测试"的代码是一个优先事项。如果这不是我的方法,我不确定是否会有很多场合使用受保护的内部方法。


我认为受保护的内部意味着只有继承并位于同一程序集中的类才能看到该属性。那些派生类并来自不同程序集的类不能看到它。

Le:阅读Mattias Buelens的评论。