前景提要:
最近大家都在面試,討論最多、最基礎的問題,莫過於“關於const和readonly常見的筆試題剖析”,等等的大牛解析。我就是一個小菜,只不過,有點不敢苟同大牛的意見。廢話少說,進入重點。
小斗大牛:
關於const和readonly常見的筆試題剖析(http://www.cnblogs.com/wolf-sun/p/3599209.html)
上個帖子有牛回我,有些偏激,可能有點吧,但是我不想看到所謂大牛,誤人子弟,而且還說的糊里糊塗!
我只是一只小菜鳥!帶着懷疑的精神,來探究問題!
小批斗一下:
批1:自定義含義
大牛啊,您在給創造微軟的定義嗎?
compile-time constant
runtime constants
MSDN已有明確翻譯了
編譯時常數、運行時常數(這兩個多么好理解啊!)
批2:無意義的反編譯,講解
這是干嘛,又引出一個關鍵字。我去!const→literal,readonly→initonly,這是啥意思呢!
直奔主題:
1、先看面試題:(增加一點復雜性)
static readonly int A = C * D;
static readonly int B = 10;
const int C = 5;
static readonly int D = B * C;
static void Main(string[] args)
{
Console.WriteLine("{0},{1},{2},{3}", A, B, C, D);
Console.ReadKey();
}
問:A、B、C、D數值是多少?
答案:是A:0、B:10、C:5、D:50
這就是答案了,想要面試成功,到這里就可以了。
想要知道為啥,為什么?或者多加點工資?或者其他類似問題,怎么解決?
那您還需要繼續看下去。
2、解釋說明工具:ILSpy、Refelector、MSDN(個人理解,這里其實不用反編譯,看看MSDN 你都能明白的。)
3、正文開始:
先來一個擴展延深哈?
面試時要是答案,您不太知道,你還可以劍走偏鋒,
3.1 你可以回答面試官,我什么時候用它,使用的場景。
Readonly:場景1,數據庫連接字段。
場景2,定義一個人物類時,比如生日,性別,在構造一個人的時候就有的,不可能變的。當然現在可以直接就是一個只讀屬性。
Const :一般是固定不變的,通用的,大家都知道的,const PI=3.14,這個我用的比較少,請大牛補充啊
3.2 不走尋常路
Console.WriteLine("{0},{1},{2},{3}", A, B, C, D);
這句可以說,也是必須要說的,
Console.WriteLine("{0},{1},{2},{3}", A.ToString(), B.ToString(), C.ToString(), D.ToString());
看看,有啥不同,不就是多了ToString()嗎?
大牛最愛沒事去反編譯了,咱也要晉級大牛。去反編譯吧!
這里有詳細記錄了,畢竟不是本文主要內容:” C# 程序性能提升篇-1、裝箱和拆箱,枚舉的ToString淺析”
簡單說,就是發生了裝箱,將int裝入obj。效率的丟失。(這里值得你去反編譯一下看看原理,裝箱、拆箱是很影響效率滴。)
4. 知識探究
原本的英文(MSDN):
Compile-time constant
Runtime constant
個人認為你看看英文可能就會明白了,一個是編譯時,一個是運行時(這兩個不懂的話,看來你要好好復習一下大學課程,計算機系的應該都會知道的吧!)。
還用繼續說下去嗎?編譯時常數,就是編譯額過程中就確定了唄。運行時常數,運行中才去賦值,使用的東東。不管是編譯時的還是運行時的變量、常量,所有的(那個全局、局部變量作用域就不說了啊)都會在編譯的時候聲明。不是賦值啊!
進入MSDN 搜索一下 :http://msdn.microsoft.com/zh-CN/
Readonly定義:readonly 關鍵字是可以在字段上使用的修飾符。 readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.' xml:space="preserve">當字段聲明包括 readonly 修飾符時,該聲明引入的字段賦值只能作為聲明的一部分出現,或者出現在同一類的構造函數中。
Const定義:使用 const 關鍵字聲明一個常量字段或局部常量。 此關鍵字指定字段或局部變量的值是常數,不能被修改。
Static定義: 使用 static 修飾符聲明屬於類型本身而不是屬於特定對象的靜態成員 static 修飾符可用於類、字段、方法、屬性、運算符、事件和構造函數,但不能用於索引器、析構函數或類以外的類型。
小結一下:可以看出static與readonly、const沒有一毛錢關系。而且在const中,也有明確的說明:不允許在常數聲明中使用 static 修飾符。
不論是在const,還是在readonly的MSDN中均有,一段醒目的明確的提示:
看到這里,應該明白了吧
5.還不懂?ok,服了您了,分析下代碼
程序編譯:
聲明了所有字段,而且C=5了。這個是編譯時的常量。你可以直接理解成C就是5,5就是C。
此時運行時常量A=0,B=0,C=0。進行聲明初始化。(int 默認值是0)
程序運行(程序順序執行,不用我說了吧):
static readonly int A = C * D;// 這時沒執行前A=0,C=5(編譯時,就編譯了,運行中改都改不了),D=0(還沒被賦值呢啊,沒到那句呢!),
那就:執行吧;結果是A=5*0=0;
static readonly int B = 10; //這句,沒亮點,沒內涵,過了吧,就是簡單賦值操作
const int C = 5;//這句得說,運行時,他都不執行,編譯時就執行了,這下你不想着改了吧。可以自己調試一下試試。
static readonly int D = B * C;// 這句也就簡單了吧D=10*5=50;
注意:在說明一下readonly只能在定義或者構造函數中賦值吧,其實,這就是微軟就這么規定的,你記住這么用就行了。沒有什么延深的,用途不是太多,一般場景以上也提到了。
后議:即使反編譯了:也就是換了一個稱呼const→literal,readonly→initonly
個人愚解:原來啊!framework那些大牛、開發工程師開發framework時,literal是內部使用名稱,等到后來發布了,為了其他程序猿降低學習成本等,因為原來C++什么的都是const啊,所以C#對外發布也得叫這個。還是統一名稱吧。Readonly也是就是換了一個名稱啊。難道還有其他內涵?(請求大牛繼續反編譯光臨指導啊!)
所以說大牛,以上是我不敢苟同的。您反編譯了那么多,就告訴大家一個別名嗎?
還不如說Console.WriteLine()這里發生裝箱,拆箱來的實惠些!(裝箱拆箱:可以參看:C# 程序性能提升篇-1、裝箱和拆箱,枚舉的ToString淺析)