32

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

在类中access modifiers覆盖 a 时,我们不能修改, 。考虑命名空间中的类virtual methodderivedControlSystem.Web.UI

public class Control : IComponent, IDisposable,...
{ 
   protected internal virtual void CreateChildControls()
   { }
   .
   .
}

现在考虑这个

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()
        { }  
    }

任何机构都可以解释这一点吗?谢谢

4

3 回答 3

55

在派生类中重写虚方法时,我们不能修改访问修饰符。

这种说法是错误的。在您描述的情况下,您可以而且必须更改访问修饰符。在其他情况下,您不得更改访问修饰符。

我请您参考规范的第 10.6.4 节,其中指出:

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

推理很简单。

你,阿萨德,有一个银行账户,BankAccount。

你有一个房子。你在房子里租了一个房间给你最好的朋友查理。

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

你有一个儿子 Elroy,他住在公寓里。

埃尔罗伊有一个儿子,你的孙子弗兰克,他住在蒙古包里。

埃尔罗伊有一个最好的朋友格雷格,他和他住在公寓里。

您将您的 BankAccount 访问权限授予您自己、居住在 House 中的任何人以及您的任何后代。所以可以访问银行账户的人是 Asad、Charlie、Elroy 和 Frank。

大卫无法访问,因为他既不是你,也不是你的后代,也不是住在房子里。他是你室友的孩子是无关紧要的;他无法访问您的 BankAccount。

Greg 也无法访问您的银行帐户。他不是你的后裔。他不住在议院。他与您的后代住在一起这一事实并不赋予他与您的后代相同的权利。

现在我们来到了问题的关键。不允许 Elroy 将对您的 BankAccount 的访问权限扩展到 Greg。你拥有那个银行账户,你说“我自己,我的后代和我的室友”。您的孩子无权将 BankAccount 的可访问性扩展到您最初设置的范围之外。

当 Elroy 描述他对 BankAccount 的访问权限时,他只能说“我将访问权限授予我自己和我的后代”,因为这是您已经允许的。他不能说“我向我自己、我的后代和 Condo 的其他居民授予访问 BankAccount 的权限”。

只是要清楚:

  • 我和我的后代获得访问权限 = 受保护的访问权限
  • 我和我的室友获得访问权限 = 内部访问权限
  • 我和我的后代以及我的室友获得访问权限 = 受保护的内部访问权限
  • 控制=阿萨德
  • CreateChildControls = BankAccount
  • 房子 = System.Web.DLL
  • Charlie = System.Web.DLL 中的任何类型
  • David = 程序集 Apartment.DLL 中 Charlie 的派生类型
  • Elroy = someClass
  • Condo = 包含 SomeClass 的程序集
  • Greg = Condo.DLL 中的其他类
  • Frank = Yurt.DLL 中 someClass 的派生类型
  • Yurt = 其他一些组件
于 2010-03-03T23:50:01.410 回答
7

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

于 2010-03-03T23:23:23.983 回答
3

受保护的内部意味着受保护的或内部。因此,如果通过覆盖原始程序集外部,您可以将其标记为受保护的内部,您将允许与覆盖程序相同的程序集中的其他类调用此方法。这实际上意味着原始父级的内部封装将被违反。

于 2010-03-03T23:25:30.080 回答