C#中的readonly跟const用法小結

總結一下常量和只讀字段的區別:程序員

由來:面試

      筆者也是在看歐立奇版的《.Net 程序員面試寶典》的時候,才發現本身長久以來居然在弄不清出二者的狀況下,混用了這麼長的時間。的確,const與readonly 很像,都是將變量聲明爲只讀,且在變量初始化後就不可改寫。那麼,const與readonly 這兩個修飾符到底區別在什麼地方呢?其實,這個牽扯出C#語言中兩種不一樣的常量類型:靜態常量(compile-time constants)和動態常量(runtime constants)。這二者具備不一樣的特性,錯誤的使用不只會損失效率,並且還會形成錯誤。數組

      首先先解釋下什麼是靜態常量以及什麼是動態常量。靜態常量是指編譯器在編譯時候會對常量進行解析,並將常量的值替換成初始化的那個值。而動態常量的值則是在運行的那一刻纔得到的,編譯器編譯期間將其標示爲只讀常量,而不用常量的值代替,這樣動態常量沒必要在聲明的時候就初始化,而能夠延遲到構造函數中初始化。函數

      當你大體瞭解上面的兩個概念的時候,那麼就能夠來講明const與readonly了。const修飾的常量是上述中的第一種,即靜態常量;而readonly則是第二種,即動態常量。那麼區別能夠經過靜態常量與動態常量的特性來講明:ui

      1)const修飾的常量在聲明的時候必須初始化;readonly修飾的常量則能夠延遲到構造函數初始化 對象

      2)const修飾的常量在編譯期間就被解析,即常量值被替換成初始化的值;readonly修飾的常量則延遲到運行的時候blog

      此外const常量既能夠聲明在類中也能夠在函數體內,可是static readonly常量只能聲明在類中。ci

一.值的區別:字符串

常量(const):是已知的,不能修改的值。const都是靜態的,不能使用static修飾。用類來訪問編譯器

只讀字段(readonly):只能在構造函數中修改的,只讀字段的值不能在編譯時肯定,而是在運行時肯定的。

readonly能夠用static修飾,也能夠不用。

二.賦值方法區別:

常量(const):只能在聲明時賦值,常量的值在編譯時就已經肯定,在程序中不能改變。

只讀字段(readonly):只讀字段能夠在聲明時或者在構造函數內賦值。只讀字段能夠是靜態字段(一個類只有一個值),也能夠是實例字段(每個實例有本身的值)。

Const 定義的是靜態常在對象初始化的時候賦值.const修飾的常量必須在聲明的同時賦值,之後不能改變它的值.屬於編譯時常量。不能用new初始化。

const修飾的常量爲靜態變量,不可以爲對象所獲取

Readonly 是隻讀變量.屬於運行時變量.能夠在類constructor裏改變它的值.不能做用於局部變量。

(所以被Readonly修飾的變量只能在初始化--聲明初始化或構造器初始化--的過程當中賦值,其餘地方不能進行對只讀域的賦值操做)

readonly僅僅用於修飾class的field(字段)

        public const int x = 10;
        public const string a = "s";
        public const User CA = null;
        public readonly User CANew = new User();
        public readonly User animal;
        protected static readonly DateTime StartTime;

  

readonly和const都是用來標識常量的。

    • const可用於修飾class的field或者一個局部變量(local variable);而readonly僅僅用於修飾class的field。
    • const常量的值一定在編譯時就已明確而且恆定的;而readonly常量卻有一點不一樣,那就是其值能夠在運行時編譯,固然,它也必須遵照做爲常量的約束,那就是值必須恆定不變。
    • const常量必須在聲明的同時對其進行賦值,而且確保該值在編譯時可肯定並恆定;而readonly常量則能夠根據狀況選擇在聲明的同時對其賦予一個編譯時肯定並恆定的值,或者將其值的初始化工做交給實例構造函數(instant constructor)完成。如:public readonly string m_Now = DateTime.Now.ToString();,m_Now會隨着運行時實際狀況變化而變化。
    • const常量屬於類級別(class level)而不是實例對象級別(instant object level),而且它不能跟static結合一塊兒使用,該常量的值將由整個類的全部實例對象共同分享(詳細論述參見後面的Remark區域)。
    • readonly常量既能夠是類級別也能夠是實例對象級別的,這取決於它的聲明以及初始化工做怎麼實施。readonly能夠與static結合使用,用於指定該常量屬於類級別,而且把初始化工做交由靜態構造函數(static constructor)完成(有關如何把readonly常量聲明爲類級別或實例對象級別的論述清參見後面的Remark區域) 。
    • 能被const修飾聲明爲常量的類型必須是如下的基元類型(primitive type):sbyte,byte, short,ushort, int,uint,long,ulong, char,float, double,float, bool,decimal, string。
    • object, 數組(Array)和結構(struct)不能被聲明爲const常量。
    • 通常狀況下,引用類型是不能被聲明爲const常量的,不過有一個例外:string。該引用類型const常量的值能夠有兩種狀況,string或null。其實,string雖然是引用類型,可是.NET卻對它特別處理,這種處理叫作字符串恆定性(immutable),使得string的值具備只讀特性。                                                
相關文章
相關標籤/搜索