區分const,static,readonly,volatile四個關鍵字


const:表示常量,變量的值是絕不會被改變的,常量的值是在編譯時就已經確定了。編譯器會把常量的值保存在程序集的元素據里面,在C#里面,下面列舉的簡單類型才能被定義為 常量:Boolean,  Char,  Byte,  SByte,  Int16,  UInt16 ,  Int32,  UInt32 ,  Int64, UInt64 ,  Single ,  Double ,  Decimal, String。如果定一個引用類型為常量,則必須把該變量的值設為null。因為常量的值是不會改變的,所以常量也常常被認為是定義的類型的一部分。換句話說,常量通常也是靜態的。當定義一個常量符號,編譯器會在程序集的元素據里面查找它的值,並把值嵌入到生成的IL里面,也因此在運行時,常量不需要分配任何內存。當然,也不能獲取常量的地址以及通過引用的方式傳遞常量。這些限制讓常量不能很好的跨程序集版本。

例如:

namespace TypeTest
{
    public sealed class SomeLibType
    {
        public const Int32 MaxEntriesInList = 50;
    }

    public sealed class Program
    {
        public static void Main()
        {
            Console.WriteLine("最大的整型的數值為:" + SomeLibType.MaxEntriesInList);
        }
    }
}

查看下Main部分的IL代碼可以清楚知道常量的值已經嵌入在IL代碼里面了,如下:

其實我們還可以看看關於定義的MaxEntriesInList,之前有說過常量一般也是靜態的,如下:

 

static:表示類型狀態的一部分,靜態意味着共享。相對於C++,C#里面沒有全局函數和全局變量的概念,等效的是使用靜態。兩者在功能上沒有什么差異,只是靜態字段和方法可以使用訪問修飾符。靜態類對應的IL會自動標記為abstract和sealed。

readonly:只有在構造函數里面才能改變它的值,只能用於字段,不能用於局部變量。修飾數組時,不會凍結數組的內容,只會凍結數組的元素數量,因為無法將只讀字段賦值為一個新的實例。不過,數組中的單個元素是可寫的。

volatile:編譯器或CPU有時會對代碼進行優化,是指令不按照它們編碼的順序執行,或者干脆拿掉一些無用的指令。若代碼在一個線程上執行,這樣的優化沒有什么影響。如果在多線程環境下,就肯能造成出乎意料的效果。這時可以使用volatile來強迫所有的讀寫操作按照代碼指定的順序發生。

 

注   《CLR via C#》(Jeffrey Richter著)——.NET 界的經典之作,讀的過程寫點筆記跟大家分享,我也推薦大家看英文版,能夠直接領會原意 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM