2

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视为 的成员BB无法读取或写入foo

4

3 回答 3

8

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

如果这是一个私有实例变量,那么它将是从 派生的任何类型的实例的任何实例的状态的一部分A,因此它将继承状态。如果您考虑继承对象的状态和行为,我认为这是有道理的。

(您可能对静态部分或私有部分感兴趣;它们有点正交。)

于 2013-01-28T14:39:41.323 回答
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 ,但是您会仅仅因为在某些源代码位置中无法通过名称访问该字段而否认这一事实吗?将“继承”的定义与“可访问”的定义联系在一起,有什么令人信服的价值?

简单地使这两个概念正交要容易得多。“继承”的意思是“这个基类型的成员也是派生类型的成员”。可访问性是访问源代码是否在声明成员的可访问域内的问题。它们彼此关系不大,所以我们不要不必要地将它们混为一谈。

于 2013-01-28T16:59:32.803 回答
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实例时,它有它自己的价值valuevalue虽然定义中无法访问该字段Child(因为它是私有的);它只能通过Parent公开的可访问的方法/属性访问。

于 2013-01-28T15:12:36.423 回答