为什么难以接近的成员被认为是继承的?

时间:2013-01-28 14:36:49

标签: c# inheritance

C#规范声明:

  

基类成员的声明可访问性无法控制   成员是否继承 - 继承扩展到任何成员   这不是实例构造函数,静态构造函数或析构函数。   但是,在派生类型中可能无法访问继承的成员,   要么是因为它声明了可访问性,要么是因为它是隐藏的   通过类型本身的声明。

为什么无法访问的成员被认为是继承的?为什么这样的区别是可行的?

作为一个具体的例子

class A
{
    const string foo = "c";

    internal void DoWork() { }
}

class B: A
{
    const string bar = "d";//renamed to foo does not appear to have a noticeable impact
    B() { bar = foo; }//inaccessible due to protection level

    internal new void DoWork() { }//hide inherited member
}

在我看来,在运行时继承意味着共享状态和/或行为。在foo的情况下,这样的事情不会发生。

是否继承B的行为最多DoWork()。因此,DoWork()成为B的成员是直观且相关的。另一方面,为什么foo被视为B的成员? B无法读取或写入foo

3 个答案:

答案 0 :(得分:8)

在您的情况下,您谈论的是const,这是隐式静态的。无论如何,静态成员实际上不会被继承。刚刚检查了规范,这意味着静态成员继承 - 但由于它们不代表状态而不能成为多态的一部分,因此它至少是一种“不同”的继承。我认为静态成员仅仅是“通过简单名称可用”到派生类,假设它们完全可以访问 - 换句话说,它与名称解析相关而不是真正的继承。

如果这是一个私有的实例变量,那么它将是从A派生的任何类型的实例的任何实例的状态的一部分,因此将< / em>是继承状态。如果你考虑一个对象的状态和行为被继承,那么在我看来这是有意义的。

(可能值得清楚的是你是否对静态部分或私有部分感兴趣;它们有点正交。)

答案 1 :(得分:6)

本文可能会对您有所帮助。

http://ericlippert.com/2011/09/19/inheritance-and-representation/

  

为什么无法访问的成员被认为是继承的?为什么这样的区别是可行的?

最好问一个相反的问题:为什么制定一条规则说难以接近的成员不会被继承?让我们考虑这样一条规则的后果。

首先,如果你有

class B
{
  internal int x; 
}
class D1 : B {}
// in another assembly
class D2 : B {}

你会说x是由D1继承而不是由D2继承?这看起来很奇怪。或者这个案例呢:

class B
{
  private int x;
  private class D1 : B {}
}
class D2 : B {}

同样,你会说x是由D1继承而不是由D2继承?

在每种情况下,派生类都有一个整数字段x ,但你只是因为某些字段无法通过名称访问而拒绝 fact 源代码位置?将“继承”的定义与“可访问”的定义联系起来,有什么吸引人的价值?

简单地使两个概念正交是容易得多的。 “Inherited”表示“基类型的此成员也是派生类型的成员”。可访问性是访问源代码是否在声明成员的可访问域内的问题。他们彼此没什么关系,所以不要让他们不必要地混淆。

答案 2 :(得分:2)

通过演示最容易解释:

public class Parent
{
    private int value;
    public virtual int GetValue()
    {
        return value;
    }
}

public class Child : Parent
{
    public int GetOtherValue()
    {
        //"value" is no accessible in this scope
        return GetValue() + 1;
    }
}

创建对象时,会为该类型的所有实例字段分配内存。 Child实际上有1个实例字段,而不是0. value继承自Parent,是Child的实例字段。创建Child实例时,它具有value的值。 value的定义中无法访问Child字段(因为它是私有的);它只能通过Parent公开哪些 可访问的方法/属性来访问。