深刻商量C#中的const、readonly症結字。本站提示廣大學習愛好者:(深刻商量C#中的const、readonly症結字)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻商量C#中的const、readonly症結字正文
起首弗成否定,這些在面試上會常常被面試官問起,然則你答復的讓面試官滿足嗎?固然假如你曉得了這些道理,也許你就不
怕了。既然說到了道理,我們照樣從MSDN說起。
一:值得斟酌的幾個處所
1.先來看看msdn下面對const是怎樣說的,我們會看到。不克不及修正,編譯經常量這些症結性信息。
Q: const為何不克不及被修正。
A:這個很簡略,許多教科書下面都說,當編譯器編譯時,會將常量的值保留在該法式集的元數據中,上面我們做個實例
看一看。
①:新建一個projectA。
// ProjectA
public class TestClass
{
public const int CTRIP = int.MaxValue;
}
再建一個MainProject,援用下projectA。
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(TestClass.CTRIP);
Console.Read();
}
}
然後我們把mainproject運轉起來。
既然我把mainproject跑起來了,而且也援用了Test.dll,適才也說了,編譯的時刻會把常量值保留在法式集的元數據中,那我們
就找一找,翻開ILdasm.exe,而且Ctrl+M。
很惋惜,我並沒有找到Ctrip的符號,也沒有找到int.MaxValue,也沒有找到所謂的0x7fffffff,卻是找到了一個Assembly的一些版本信息的元數據,那末這時候候你能夠會困惑了,畢竟const的值有無保留到Assembly外面去呢?很簡略的一個驗證辦法就是,把Mainproject上面bin中的Test.dll刪除失落,看看會有怎樣樣的事業產生。
②: 聰慧的你應當想到了,既然運轉Demo.exe的時刻不再加載Test.dll,而是直接從Demo的Assembly外面獲得const值,
那是否是會有斷層的工作產生,也就是版本紛歧致的情形,好比我曾經修正了const值,然後把編譯好的dll拷貝到Mainproject的bin目次下,直接運轉Demo.exe,會不會湧現MainProject讀不到修正後的const值呢?這裡我將const改成 int.MinValue。
上面我們可以嘗嘗看。
// ProjectA
public class TestClass
{
public const int CTRIP = int.MinValue;
}
好了,看到下面的成果,就進一步左證了適才的說法,const確確切實是保留在Assembly的元數據中,這裡還要趁便提醒一下,Enum實質上是const,所以它也存在我適才說的斷層的成績,說到這裡,我想你對const的道理應當比擬熟習了,如今我們來看看Question的成績。既然是元數據,那甚麼是元數據?“描寫數據的數據” 叫做元數據,既然它是基本的描寫性數據,那末在界說好後是決對不克不及轉變的,這個界說時也就是msdn說的編譯時,是否是so easy呢?
Q: const為何要做成靜態的,而不是做成實例的
A: 其實經由過程對第一個Question的剖析,許多器械我們應當都邑名頓開,由於存在斷層的成績,那末最好的辦法就是const的值
永久也不要變,如許便可以免成績的產生,既然是永久都不變的器械,固然是隨著“類型”走比隨著“實例”走要好的多,你說對纰謬,由於static是個小緩存,沒需要new一下才發生。。。
Q: readonly字段只能在ctor中初始化嗎?
A:這個成績蠻成心思的,我們曉得readonly的意思就是只讀字段的意思,我們曉得普通的字段具有可讀寫的功效,
先照樣看看編譯器怎樣說。
從編譯器上可以看到,確切readonly的初始化還可以在“變量初始化”的時刻停止初始化,那末如許說Question的謎底應當就能否定的,然則真的是如斯嗎?我們都曉得有一個器械叫做“語法糖”,並且常常是編譯器供給給我們用的,所以真實的想看到產生了甚麼,只能用ILDasm.exe 穿透編譯器,看看究竟產生了甚麼。
從IL中可以看到,真的就是編譯器的語法糖,實質上都是在ctor中初始化的,所以說,看成績萬萬不要看外面。
注:Stsfld 用來自盤算客棧的值調換靜態字段的值。