我们说我有一个抽象类A.我在这里有一些内部类:
public abstract class A
{
public InnerOne x;
public InnerTwo y;
public A(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
public class InnerOne
{
public virtual double value(){
return 0;
}
}
public class InnerTwo
{
public virtual double value(){
return 0;
}
}
}
然后我得到了这样的孩子:
public class B: A
{
public B():base(){
}
public class InnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class InnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
所以我认为当我调用B
构造函数时,我会通过创建它的内部类实例来初始化x
和y
。但实际上它不是那样的。当我像这里调用vaule
函数时,它会返回零。
A newobject = new B();
var bv1 = B.x.value();
var bv2 = B.y.value();
是否可以强制B
类通过它的内部类对象(而不是来自父抽象类的对象)初始化它的x
和y
字段)没有重写它的构造函数?
答案 0 :(得分:1)
即使你已经在A或B中定义了类,它们仍然是公共的,它们可以在A或B之外访问。它与在A或B之外定义的类没有什么不同。
想象一下在A类和B类之外定义InnerOne
和InnerTwo
的相同代码。它将具有相同的上述行为。你的混乱根源是对内部阶级使用的误解。
为了获得100,在B内部,您需要使用覆盖这些值的实例显式替换X和Y变量的实例。除非你这样做,否则你不会得到100。
public class B: A
{
public B():base(){
X = new OverridenInnerOne();
Y = new OverridenInnerTwo();
}
public class OverridenInnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class OverridenInnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
答案 1 :(得分:1)
内心阶层' aspect(嵌入式类定义)只会分散注意力,它不起作用。
并回答这个问题:不,你不能拥有虚拟构造者'这样工作。
当然有很多方法可以将100
而不是0
作为返回值,但这个问题太过于人为,无法提出问题。
答案 2 :(得分:1)
B.x
和B.y
是A.InnerOne
和A.InnerTwo
的实例,因此您将返回的值视为0,因为这些与{B.InnerOne
无关。 1}}或B.InnerTwo
。
以下B
构造函数会将x
和y
分配给B.InnerOne
和B.InnerTwo
的实例,这些实例将返回100。
public B(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
如果您希望A
以您期望的方式工作,您需要从B
构造函数中传递您想要的内部类型,并在{{{{}}中创建它们的实例1}}构造函数,类似于:
A
使用 public B():base(typeof(InnerOne),typeof(InnerTwo)) { ... }
可以在Activator.CreateInstance
的构造函数中创建这些类型。
如果你总是希望A
以这种方式使用,那么Enigmativity的通用解决方案会更好,或者这种方式允许你为A
提供多个构造函数,这样你就可以选择传递不同的类型。 / p>
答案 3 :(得分:1)
你可以这样做,但是你必须改变班级A
的定义 - 它会变得非常毛茸茸。
此处A
:
public abstract class A<I1, I2>
where I1 : A<I1, I2>.InnerOne, new()
where I2 : A<I1, I2>.InnerTwo, new()
{
public InnerOne x;
public InnerTwo y;
public A()
{
this.x = new I1();
this.y = new I2();
}
public class InnerOne
{
public virtual double value()
{
return 0;
}
}
public class InnerTwo
{
public virtual double value()
{
return 0;
}
}
}
这里B
:
public class B: A<B.InnerOne, B.InnerTwo>
{
public B():base(){ }
public class InnerOne: A<InnerOne, InnerTwo>.InnerOne
{
public override double value()
{
return 100;
}
}
public class InnerTwo: A<InnerOne, InnerTwo>.InnerTwo
{
public override double value()
{
return 100;
}
}
}