用 protected 覆盖受保护的内部!

发布于 2024-08-23 07:46:36 字数 858 浏览 8 评论 0原文

这是此 问题一小时前提出。

当重写派生类中的虚拟方法时,我们无法修改访问修饰符。考虑 System.Web.UI 命名空间中的 Control 类,

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

有人可以解释一下吗?谢谢

This is an extension for this question asked an hour ago.

We cannot modify the access modifiers, when overriding a virtual method in derived class. Consider Control class in System.Web.UI namespace

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

Now Consider This

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

can any body explain this ? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

何止钟意 2024-08-30 07:46:36

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

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

我建议您参阅规范的第 10.6.4 节,其中规定:

覆盖声明不能更改
虚拟的可访问性
方法。但是,如果被覆盖
基本方法受内部保护并且
它是在不同的程序集中声明的
比包含的程序集
覆盖方法然后覆盖
方法声明的可访问性必须
受到保护。

推理很简单。

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

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

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

你有一个儿子,埃尔罗伊,住在公寓里。

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

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

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

大卫无法进入,因为他既不是您,也不是您的后裔,也不住在众议院。他是你室友的孩子并不重要;他是你室友的孩子并不重要。他无法访问您的银行帐户。

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

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

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

需要明确的是:

  • 我和我的后代获得访问权限 = 受保护的访问权限
  • 我和我的室友获得访问权限 = 内部访问权限
  • 我和我的后代和我的室友获得访问权限 = 受保护的内部访问权限
  • 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 =其他一些程序集

We cannot modify the access modifiers when overriding a virtual method in derived class.

That statement is false. You can and must change the access modifiers when in precisely the situation you describe. In other situations you must not change the access modifiers.

I refer you to section 10.6.4 of the specification, which states:

an override declaration cannot change
the accessibility of the virtual
method. However, if the overridden
base method is protected internal and
it is declared in a different assembly
than the assembly containing the
override method then the override
method’s declared accessibility must
be protected.

The reasoning is straightforward.

You, Asad, have a bank account, BankAccount.

You have a House. You rent a room in House to your best friend Charlie.

Charlie has a son, David, who lives in an Apartment.

You have a son, Elroy, who lives in a Condo.

Elroy has a son, your grandson, Frank, who lives in a Yurt.

Elroy has a best friend Greg who lives in the Condo with him.

You grant access to your BankAccount to yourself, to anyone living in House, and to any of your descendents. So the people who can access the bank account are Asad, Charlie, Elroy, and Frank.

David does not get access because he is neither you, nor your descendent, nor is he living in House. That he is a child of your housemate is irrelevant; he doesn't get access to your BankAccount.

Greg does not get access to your bank account either. He is not your descendent. He does not live in House. The fact that he is living with your descendent does not grant him the same rights as your descendent.

Now we come to the crux of the matter. Elroy is not allowed to extend access to your BankAccount to Greg. You own that BankAccount, and you said "myself, my descendents and my housemates". Your children don't have the right to extend the accessibility of BankAccount beyond what you initially set up.

When Elroy describes what access he has to BankAccount, he is only allowed to say "I grant access to this to myself and my descendents", because that is what you already allowed. He cannot say "I grant access to BankAccount to myself, my descendents and to the other residents of Condo".

Just to be clear:

  • I and my descendents get access = protected access
  • I and my housemates get access = internal access
  • I and my descendents and my housemates get access = protected internal access
  • Control = Asad
  • CreateChildControls = BankAccount
  • House = System.Web.DLL
  • Charlie = any type in System.Web.DLL
  • David = derived type of Charlie in assembly Apartment.DLL
  • Elroy = someClass
  • Condo = your assembly containing SomeClass
  • Greg = some other class in Condo.DLL
  • Frank = derived type of someClass in Yurt.DLL
  • Yurt = some other assembly
苦笑流年记忆 2024-08-30 07:46:36

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

Because, while the terminology is different, overriding it as protected keeps the visibility of the member the same. If you were allowed to override it as protected internal, then you would suddenly be exposing the member to any other type in your assembly.

我很OK 2024-08-30 07:46:36

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

Protected internal means protected OR internal. So if by overriding outside the original assembly you were allowed to mark it protected internal you would be allowing other classes in the same assembly as the overrider to call this method. That would effectively mean that original parent's internal encapsulation would be violated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文