使用受父保护的构造函数的实例子类字段
本文关键字:构造函数 实例 子类 字段 保护 | 更新日期: 2023-09-27 18:19:28
>简化情况
public class A {
protected A() { }
protected A Make() { return new A(); }
}
public class B : A {
A a = new A(); //inaccessible due to protection level
B b = new B();
private B()
{
A c = new A();//inaccessible due to protection level
a = new A(); //inaccessible due to protection level
a = Make();
}
}
为什么无法使用受保护的 A 类构造函数在类 B 中创建 A 实例?
在我看来,受保护的构造函数就像受保护的方法,所以应该可以在子类中运行它。
为什么无法使用类 A 在类 B 中创建 A 的实例 受保护的构造函数?
不能使用 new
修饰符调用受保护的构造函数,因为受保护构造函数的用途是只能从派生类的角度调用它,因此从"外部"不可见。
编译器不会推断对new A()
的调用正在从 B
的实例完成。这就是为什么构造函数语法可用,以保证如何调用基构造函数的约定。
您可以在声明B
构造函数时调用A
构造函数:
public B(string foo) : base(foo)
这是代表您为默认构造函数实际完成的操作。例如:
public class A {}
public class B : A
{
public B() {}
}
将产生以下 IL:
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x205a
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void A::.ctor() <--- This.
IL_0006: ret
} // end of method B::.ctor
一种黑客方法(我会避免这样做(是创建这样的实例可以通过重载来实现Activator.CreateInstance
重载,该重载接受指示构造函数是非公共的bool
标志:
var b = (B)Activator.CreateInstance(typeof(B), nonPublic: true);
你可以制作构造函数A
protected internal
:
public class A
{
protected internal A() { }
protected A Make() { return new A(); }
}
因此,类型或成员可由声明该类型或成员的程序集中的任何代码访问,也可以从另一个程序集的派生类中访问。
查看此链接以获取更多详细信息: Many Questions: Protected Constructors
.
protected
成员只能在派生类(子类(中通过派生类(或进一步派生类(类型的实例引用来访问。
下面是一个使用方法而不是构造函数的示例:
class B
{
protected void M() { }
}
class C : B
{
void X()
{
M(); // OK, same as this.M()
}
void Y(C otherC)
{
otherC.M(); // OK
}
void Z(B otherB)
{
otherB.M(); // compile-time error CS1540
}
}
所以在上面的例子中,你可以在C
内部的C
上调用M
,但不能在C
内部的B
上调用M
。
实例构造函数的示例与此类似。new
对象表达式就像在 new
之后编写的类型(新(对象上调用实例成员(实例构造函数(。
尝试将代码修改为
a = this.Make();
希望它可以帮助您更好地理解代码。根据 MSDN
受保护的成员可以在其类中访问,也可以由派生类实例访问。
因此,当您调用this.Make()
时,您正在derived class instances
中访问protected constructor
。在 class B
中调用 new A()
时,当前实例this
和要创建的新实例是两个不同的实例。您实际上是在A
或A
派生类之外访问A
的构造函数。