国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

深入探討C#中的const、readonly關鍵字

2020-01-24 02:31:48
字體:
來源:轉載
供稿:網友

首先不可否認,這些在面試上會經常被面試官問起,但是你回答的讓面試官滿意嗎?當然如果你知道了這些原理,或許你就不

怕了。既然說到了原理,我們還是從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 用來自計算堆棧的值替換靜態字段的值。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西藏| 夏河县| 福建省| 赞皇县| 思茅市| 司法| 岱山县| 长岛县| 文成县| 定南县| 陕西省| 新津县| 河池市| 广水市| 富锦市| 合水县| 赤峰市| 九龙城区| 通辽市| 米易县| 滦南县| 禹州市| 大名县| 监利县| 宁武县| 延安市| 青冈县| 长春市| 汕头市| 霍城县| 高雄县| 易门县| 屏东市| 黎平县| 荣昌县| 武宁县| 雅安市| 连山| 阜城县| 江永县| 日喀则市|