代码之家  ›  专栏  ›  技术社区  ›  Asad

用protected重写protected internal!

  •  26
  • Asad  · 技术社区  · 15 年前

    这是一个 extension 为此 question 一小时前问。

    我们不能修改 access modifiers ,当重写 virtual method 在里面 derived 班级。考虑 Control 班在 System.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()
            { }  
        }
    

    有人能解释吗?谢谢

    3 回复  |  直到 8 年前
        1
  •  47
  •   Eric Lippert    15 年前

    当重写派生类中的虚拟方法时,不能修改访问修饰符。

    那句话是假的。你可以 必须 在您描述的情况下更改访问修饰符。在其他情况下,不能更改访问修饰符。

    请参阅本规范第10.6.4节,其中规定:

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

    理由很简单。

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

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

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

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

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

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

    你允许你自己,任何住在房子里的人,以及你的任何后代使用你的银行账户。所以能进入银行账户的人是阿萨德、查理、埃尔罗伊和弗兰克。

    大卫不能进去,因为他既不是你,也不是你的后裔,也不是住在家里。他是你室友的孩子是无关紧要的,他无法进入你的银行账户。

    格雷格也不能进入你的银行账户。他不是你的后裔。他不住在房子里。他和你的后代住在一起,这一事实并没有赋予他和你的后代同样的权利。

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

    当埃尔罗伊描述他对银行账户的访问权限时,他只允许说“我允许我自己和我的后代访问这个”,因为这是你已经允许的。他不能说“我允许我自己、我的后代和公寓的其他居民使用银行账户”。

    只是想说清楚:

    • 我和我的后代获得访问=受保护的访问
    • 我和我的室友可以进入=内部进入
    • 我和我的后代还有我的室友都能进入受保护的内部通道
    • 控制=ASAD
    • createChildControls=银行账户
    • house=系统.web.dll
    • charlie=system.web.dll中的任何类型
    • david=程序集公寓中查理的派生类型.dll
    • 埃尔罗伊=某个阶级
    • condo=包含某个类的程序集
    • greg=condo.dll中的其他类
    • frank=yurt.dll中SomeClass的派生类型
    • 蒙古包=其他的集会
        2
  •  6
  •   John Rasch    15 年前

    因为,虽然术语不同,但是 protected 保持成员的可见性不变。如果你被允许重写它 protected internal ,则会突然将成员暴露给程序集中的任何其他类型。

        3
  •  3
  •   Stephen Kennedy annamataws    8 年前

    受保护的内部是指受保护的或内部的。因此,如果通过在原始程序集外部重写,允许您将其标记为受保护的内部,则允许与重写器位于同一程序集中的其他类调用此方法。这实际上意味着原始父级的内部封装将被破坏。

    推荐文章