大家一起探討兩道C#面試題
先看C#面試題大家可以先想想結(jié)果
C#面試題1. string aString = "a" + "b" + "c"; 有幾次內(nèi)存分配;
C#面試題2. 多態(tài)的考察,如下的輸出結(jié)果。
- Code
- public class Program
- {
- static void Main(string[] args)
- {
- A a = new C();
- a.Show();
- Console.ReadKey();
- }
- }
- public class A
- {
- public virtual void Show()
- {
- Console.WriteLine("A");
- }
- }
- public class B:A
- {
- public new virtual void Show()
- {
- Console.WriteLine("B");
- }
- }
- public class C:B
- {
- public override void Show()
- {
- Console.WriteLine("C");
- }
- }
我自己的答案如下
答案
我的答案是:
1次,或者沒有
A。
引入和一點(diǎn)分析
1 第一個問題是值類型和引用類型說起的。面試的人問我關(guān)于值類型和引用類型。我blabla說了些堆棧和內(nèi)存分配。我說了string是特殊的引用類型,他不可變。然后引出這個問題。string aString = "a" + "b" + "c"; 有幾次內(nèi)存分配。按著開始的引導(dǎo)。我的答案是a一次,b一次,ab一次。因?yàn)閍b還是string不可變。那么abc還需要一次。具體不數(shù)是幾次。面試官給我的答案也是很多次。他也是這么認(rèn)為的。
回來之后我寫了這個代碼??戳讼翴L發(fā)現(xiàn)不是這么回事。CLR可以直接生成字符串"abc".
后來請教高人,多少明白是怎么個意思了。因?yàn)?的含義編譯器是知道的就是編譯器知道string不可變,所以提前在生成的IL代碼里面寫死了,寫在數(shù)據(jù)段里面了,等同于寫死了。如果編譯器比較先進(jìn)的話他能檢測到aString也不需要內(nèi)存。
- 2 看IL
IL中也是非常的清楚的現(xiàn)實(shí)了調(diào)用的是A中的Show方法。我的理解是:
A定義了方法show,注意B中的show方法雖然也是virtual的,但是之前有一個new。B從新定義了一個方法show。
C 中的override的是B定義的那個方法。
【這個時(shí)候?qū)嶋H上C里面有兩個show方法。】這段有待於斟酌。
出現(xiàn)這種情況的時(shí)候 如果通過基類調(diào)用的話 就選距離那個基類最近的方法。所以會調(diào)用A中的Show方法。
看了回復(fù)覺得徐少俠解釋的非常好??!
用距離基類近來解釋似乎不科學(xué)
A類有虛Show
B類就已經(jīng)有兩個Show方法了
C也的確有兩個
由于最終的變量是A類型的,因此搜索函數(shù)入口時(shí)從基類A的入口表開始,根據(jù)虛方法定義查找子類的重寫方法,但是由于無法再B類定義中發(fā)現(xiàn)override方法
則最終調(diào)用的是A的現(xiàn)實(shí)
Ivony...解釋同樣精彩。
回復(fù) 引用 查看 刪除 #27樓2009-08-10 14:56 | Ivony...
- public class C : B
- {
- //...
- public void Test()
- {
- ((A) this).Show();
- base.Show();
- this.Show();
- }
- }
- =======================================
- Code2
- public class Program
- {
- static void Main(string[] args)
- {
- A a = new C();
- a.Show();
- Console.ReadKey();
- }
- }
- public class A
- {
- public virtual void Show()
- {
- Console.WriteLine("A");
- }
- }
- public class B:A
- {
- public override void Show()
- {
- Console.WriteLine("B");
- }
- }
- public class C:B
- {
- public new void Show()
- {
- Console.WriteLine("C");
- }
- }
【編輯推薦】