c# - 为什么子类不能使用基类保护的构造函数创建新对象?

标签 c# inheritance constructor protected

我正在将一些 Java 代码移植到 C#,我遇到了这个用于复制对象的习惯用法:

class Base
{
    int x;
    public Base(int x) { this.x = x; }
    protected Base(Base other) { x = other.x; }
}

class Derived : Base
{
    Base foo;
    public Derived(Derived other)
        : base(other)
    {
        foo = new Base(other.foo); // Error CS1540
    }
}

错误 CS1540 为:

Cannot access protected member 'Base.Base(Base)' via a qualifier of type 'Base'; the qualifier must be of type 'Derived' (or derived from it)

我理解这个错误的目的:它阻止访问兄弟类型的 protected 成员。但是 Base.Base(Base) 显然不会在兄弟类型上被调用!这只是没有包含在规范中,还是我遗漏了一些不安全的原因?

编辑:啊,成语是 new Base(other.foo) 而不是 new Base(other)

最佳答案

语言规范的第 3.5.2 节和第 3.5.3 节详细说明了这一点,为方便起见,我将发布 3.5.2(它更短!)并让您自己找到 3.5.3。

In intuitive terms, when a type or member M is accessed, the following steps are evaluated to ensure that the access is permitted:

  • First, if M is declared within a type (as opposed to a compilation unit or a namespace), a compile-time error occurs if that type is not accessible.
  • Then, if M is public, the access is permitted.
  • Otherwise, if M is protected internal, the access is permitted if it occurs within the program in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (§3.5.3).
  • Otherwise, if M is protected, the access is permitted if it occurs within the class in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (§3.5.3).
  • Otherwise, if M is internal, the access is permitted if it occurs within the program in which M is declared.
  • Otherwise, if M is private, the access is permitted if it occurs within the type in which M is declared.
  • Otherwise, the type or member is inaccessible, and a compile-time error occurs.

基本上,访问基类的 protected 成员必须通过派生类的实例。正如您所说, sibling 不能访问彼此的 protected 成员,但是语言规范还禁止 child 访问基的 protected 成员,除非引用是通过 child 进行的。

关于c# - 为什么子类不能使用基类保护的构造函数创建新对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6223111/

相关文章:

c# - Unity中角色跳跃时如何禁用重力?

c# - 使用 EF 检查表中新记录的成本最低的操作

c# - 在 C# 中重复用户输入是否为空的问题

c++ - 不带多态性的抽象基类

html - html中可能有 "inheritance"吗?

php - php抽象类中的构造函数有什么用

java - 重载的构造函数

javascript - 迁移到 VS2013.4 后调用 WinRT 组件时类未注册异常

c++ - 从子类访问私有(private)继承类的名称

c++ - "explicit"构造函数对重载决议的影响