覆盖受保护的内部受保护!

Asa*_*sad 27 c# virtual-functions

这是一小时前提出的extension这个问题.

我们不能修改access modifiers重写一个时,virtual methodderived类.考虑命名空间中的ControlSystem.Web.UI

public class Control : IComponent, IDisposable,...
{ 
   protected internal virtual void CreateChildControls()
   { }
   .
   .
}
Run Code Online (Sandbox Code Playgroud)

现在考虑一下

public class someClass : System.Web.UI.Control
    { 
       // This should not compile but it does
        protected override void CreateChildControls()
        { }

       // This should compile but it does not
        protected internal override void CreateChildControls()
        { }  
    }
Run Code Online (Sandbox Code Playgroud)

任何机构可以解释一下吗?谢谢

Eri*_*ert 48

在覆盖派生类中的虚方法时,我们无法修改访问修饰符.

那句话是错误的.在您描述的情况下,您可以而且必须更改访问修饰符.在其他情况下,您不得更改访问修饰符.

我推荐你参考规范的第10.6.4节,其中规定:

覆盖声明不能更改虚方法的可访问性.但是,如果重写的基本方法在内部受到保护,并且它在与包含override方法的程序集不同的程序集中声明,则必须保护override方法声明的可访问性.

推理很简单.

你,Asad,有一个银行账户,BankAccount.

你有一所房子.你在House租了一间房间给你最好的朋友查理.

查理有一个儿子,大卫,住在公寓里.

你有一个住在公寓里的儿子Elroy.

Elroy有一个儿子,你的孙子,弗兰克,住在蒙古包里.

Elroy有一个最好的朋友Greg和他一起住在公寓里.

您可以向自己,居住在众议院的任何人以及任何后代授予访问您的BankAccount的权限.因此,可以访问银行账户的人是Asad,Charlie,Elroy和Frank.

大卫没有进入,因为他既不是你,也不是你的后代,也不是他住在众议院.他是你的室友的孩子是无关紧要的; 他无法访问您的BankAccount.

Greg也无法访问您的银行帐户.他不是你的后代.他不住在众议院.他与你的后代生活在一起的事实并没有赋予他与你的后代相同的权利.

现在我们来到问题的关键.Elroy不允许将您的BankAccount扩展到Greg.你拥有BankAccount,你说"我自己,我的后代和我的室友".您的孩子无权将BankAccount的可访问性扩展到您最初设置的范围之外.

当Elroy描述他对BankAccount的访问权限时,他只被允许说"我允许自己和我的后代访问",因为这是你已经允许的.他不能说"我允许自己,我的后代和公寓的其他居民访问BankAccount".

只是要清楚:

  • 我和我的后代获得access = protected access
  • 我和我的室友可以访问=内部访问
  • 我和我的后代和我的室友获得访问权限=受保护的内部访问权限
  • Control = Asad
  • CreateChildControls = BankAccount
  • House = System.Web.DLL
  • Charlie = System.Web.DLL中的任何类型
  • David =程序集Apartment.DLL中派生类型的Charlie
  • Elroy = someClass
  • Condo =包含SomeClass的程序集
  • Greg = Condo.DLL中的其他一些类
  • Frank = Yurt.DLL中someClass的派生类型
  • Yurt =其他一些集会

  • @Eric,有趣的比喻.一个想法 - 也许从*"谁可以访问我的银行帐户"*改为*"谁可以驾驶我的汽车"*可能使这个类比与人们更好地产生共鸣. (5认同)
  • 很好的类比......除了我不会允许住在我家的每个人访问我的银行帐户;) (2认同)

Ada*_*son 7

因为,虽然术语不同,但是覆盖它protected会使成员的可见性保持不变.如果您被允许覆盖它protected internal,那么您将突然将该成员暴露给程序集中的任何其他类型.