C# 为什么不可访问的成员被认为是继承的?

C# 为什么不可访问的成员被认为是继承的?,c#,inheritance,C#,Inheritance,C#规范规定: 基类成员声明的可访问性不控制 成员是否被继承--继承扩展到任何成员 这不是实例构造函数、静态构造函数或析构函数。 但是,继承的成员在派生类型中可能无法访问, 要么因为它声明的可访问性,要么因为它是隐藏的 通过类型本身中的声明 为什么不可访问的成员被认为是继承的?为什么会有这样的区别 作为一个具体的例子 class A { const string foo = "c"; internal void DoWork() { } } class B: A {

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
的情况下,这样的事情不会发生


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

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

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


(关于你是对静态部分感兴趣,还是对私有部分感兴趣,可能值得一提;它们有点正交。)

这可以通过演示很容易地解释:

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<代码>值继承自
父项
,是
子项
的实例字段。创建
子实例时,它有自己的
值。但是,该
字段在
子项的定义中不可访问(因为它是私有的);它只能通过
Parent
公开的可访问的方法/属性进行访问。

本文可能会对您有所帮助

为什么不可访问的成员被认为是继承的?为什么会有这样的区别

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

首先,如果你有

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,但是您会仅仅基于在某些源代码位置无法通过名称访问该字段而否认这一事实吗?制定“继承”的定义与“可访问”的定义如此紧密地联系在一起,有什么引人注目的价值


简单地使这两个概念正交要容易得多。“继承”表示“基类型的此成员也是派生类型的成员”。可访问性是指访问源代码是否在声明成员的可访问性域内。他们之间没有什么关系,所以我们不要不必要地把他们混为一谈。

我对私人部分更感兴趣。事实上,我做了这个静态只是一个糟糕的选择。正如规范中所指出的,在本节中,它没有对静态和实例进行区分……因此我认为选择是任意的。我开始看到我在“实现细节”中迷失的能力模式。