【问题标题】:What is the difference between "private" and "protected Internal"?“私有”和“受保护的内部”有什么区别?
【发布时间】:2012-06-13 04:32:33
【问题描述】:

我只想知道 private protected internal 访问说明符之间的实际区别是什么。据我所知

对自己的班级成员可见:私有且受保护的内部YES

对其他类的对象可见:两者都NO

对命名空间集合之外的其他类的对象可见:两者都NO

对命名空间集合之外的子类对象可见:两者都NO

如果 privateprotected internal 做同样的事情,那么为什么我们需要两者都只需要一个就足够了?

【问题讨论】:

标签: c# .net oop access-modifiers


【解决方案1】:
  • protected internal 成员对当前程序集另一个程序集的派生类中的任何代码可见。用技术术语来说,它是protectedinternallogical disjunction
  • private 成员仅对同一类中的代码可见。

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


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

换句话说,protected(和protected internal)成员是程序集公共 API 的一部分(因此应该记录在案)。 internal 成员不是。

【讨论】:

  • 那么我什么时候应该确定使用protected internal 而不是public
  • @François 你的最后一句话实际上不是真的; protected internal 是两者的联合,而不是交集。
【解决方案2】:

图形概览(简而言之)

【讨论】:

  • 在另一个程序集中应该有另一个名为 Derived Classes 的列 - 用于受保护的内部关键字。
  • @Lyubomir Velchev:的确,无论如何都应该有两个规则(相同的程序集,不同的程序集),并且在此图中,内部“派生类”无值应该被影线。
【解决方案3】:

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

【讨论】:

  • 所以privatechild classes as well as to other classes inside the namespace collection. 可见
  • @avirk 不,那是protected internalprivate 是最严格的访问修饰符:仅对定义类可用。
【解决方案4】:

私人

类型或成员只能被同一类中的代码访问或 结构。

受保护的内部

类型或成员可以被同一程序集中的任何代码访问, 或由另一个程序集中的任何派生类

【讨论】:

    【解决方案5】:

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

    LE:请阅读 Mattias Buelens 对此的评论。

    【讨论】:

    • 其实这是不正确的。 protected internal 表示protected union internal,所以同一个程序集中的子类和其他类都可以看到。
    • @Mattias Buelens...我的英语有点糟糕,但我想说的已经写好了。
    • 是的,一开始有点令人费解,但当你看到它是两个修饰符的 union 时,它是有道理的。
    【解决方案6】:

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

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

    这种方法确实需要一种优先编写易于“可测试”的代码的编码方法。如果这不是我的方法,我不确定我会在很多场合使用受保护的内部。

    【讨论】:

    • 访问修饰符的选择不应由您的测试需求决定。例如,如果您有一个不需要 setter 的属性,则您不会简单地添加公共 setter 以允许对其进行设置以进行测试。测试框架和模拟框架能够注入私有属性等。测试会影响您对模式甚至抽象的选择,毕竟,如果您不能模拟任何依赖项,就很难对某些东西进行单元测试。不过,测试不应影响您对访问修饰符的选择。
    • +1 Francois,我还经常看到人们将私有成员设置为“内部”,以及 InternalsVisibleToAttribute 将它们公开给单元测试程序集。
    【解决方案7】:

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

    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 的代码 使用 Z_Dll_1;

    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
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-28
      • 1970-01-01
      • 2019-07-24
      • 2014-04-26
      • 2011-05-20
      • 2010-10-27
      相关资源
      最近更新 更多