一个来北京找工作的毕业生,有天晚上问了我一道面试题,我大概看了一眼,想也没想就回答了他 输出值是1 , -1 ,后来发现错了,竟想不起来错哪儿了,来坛子里面壁,分析一下为什么Y=0,从哪儿来的?class Program
{
static void Main(string[] args)
{
B b = new B();
b.PrintFields();
Console.Read();
}
} class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields() { }
}
class B : A
{
int x = 1;
int y;
public B()
{
y = -1;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
} }结果为 1,0
1 ,-1
{
static void Main(string[] args)
{
B b = new B();
b.PrintFields();
Console.Read();
}
} class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields() { }
}
class B : A
{
int x = 1;
int y;
public B()
{
y = -1;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
} }结果为 1,0
1 ,-1
解决方案 »
- 解析HTML用哪个更好【HtmlAgilityPack VS正则表达式】
- C#后台代码如何获取js中的集合变量
- 我在c#中写了一个串行接口的类,想把它做成如同类库中的TextBox,label等拿来即可用的类,怎样做啊?
- 求教:vs2008c# 水晶报表加载失败?
- SESSION值过期报错该如何解决??
- access要怎么分组分页
- 朋友们帮帮忙,水晶报表自定义纸张
- dataGridView显示c#中查询出来的数据
- 關於報表的問題
- 如何将菜单的效果设置与C#本身的效果相同
- 请问我已经得到byte[]类型的原始视频码流,怎么在panel或picturebox里显示出来
- 如何将一个字母的ASCII码加减上几位转成其他字符
2. Derived static constructor
3. Derived instance fields
4. Base static fields
5. Base static constructor
6. Base instance fields
7. Base instance constructor
8. Derived instance constructor 调用A的构造函数的时候,Y还没有被赋值 当然是0了
http://topic.csdn.net/u/20090421/21/a3d7a5ae-d946-4276-a9d8-67353bda8a51.html跟你的问题一样
8. Derived instance constructor
就是因为7优先于8,所以~~
B b = new B();
会先构造其父类A,又因 public virtual void PrintFields() { }
在 B中 被重载了 public override void PrintFields(),
此时 Console.WriteLine("x={0},y={1}", x, y); 并还未构造之类B,
所以 y = -1; 这句还未执行,因此输入就为 1,0第二组输入的来历:
B b = new B(); 在第一组时,构造完毕了,
此时 y = -1; 这句还执行了,
再 b.PrintFields(); 此时调用 public override void PrintFields(),
所以第二组输出为 1,-1
{
static void Main(string[] args)
{
B b = new B();
b.PrintFields();
Console.Read();
}
} class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields() { }
}
class B : A
{
int x = 1;
int y;
public B()
{
y = -1;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
} }程序执行过程解释:程序由Main函数开始,B b = new B()语句调用类B的构造函数,而类B继承类A,当调用
类B的构造函数是立即调用类A的构造函数 在类A的构造函数中调用类A的PrintFields方法 又因为PrintFields方法是虚方法,在子类B中被实现,所以程序转向执行类B的PrintFields方法public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
}Console.WriteLine语句输出X,Y的值
因为定义时X被赋初值1 Y没被赋初值 但他是引用类型 默认初始值为0 所以输出结果就是X=1 Y=0
public partial class Form1 : baseForm
{
public Form1()
{
InitializeComponent();
} protected override CreateParams CreateParams
{
get
{
CreateParams p = base.CreateParams;
return p;
}
}
}
public partial class baseForm : Form
{
public baseForm()
{
InitializeComponent();
} protected override CreateParams CreateParams
{
get
{
CreateParams p = base.CreateParams;
return p;
}
}
}
重要是那个 CreateParams 属性先于构造函数执行.
之後馬上執行
下面得
--------------------------------
public B() //(1)
{
y = -1;
}
-----------------------------在執行到b的構造函數的時候調用了a(基類)的構造函數,如下
--------------------------------
public A()
{
PrintFields();
}
public virtual void PrintFields() { }
-------------------------------------------
PrintFields是虛函數調用b中的函數
----------------------------------------
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
}
---------------------------------------------
在打印之前x,y並沒有賦值~~但在程序運行之前已經初始化(棧中),所以x=1,y=0
二,隐式调用父类的构造函数
三,构造函数执行PrintFields
四,调用变量的初始化值