第二遍文章我打算把const和readonly的區別拿出來說下,由於寫代碼這麼久我都還沒搞清楚這二者的區別,實在有點慚愧,因此這一次我打算搞清楚它。數據庫
來看看MSDN的解釋:函數
readonly:readonly關鍵字是能夠在字段上使用的修飾符。當字段聲明包括readonly修飾符時,該聲明引入的字段賦值只能做爲聲明的一部分,或者出如今同一類的構造函數中。性能
const:使用 const 關鍵字來聲明某個常量字段或常量局部變量。 常量字段和常量局部變量不是變量而且不能修改。spa
太多理論的講解有些人可能看了更犯暈,因此直接寫些代碼我以爲可能比較直觀好理解。code
咱們先來看下const對象
public class ConstTest { class SampleClass { public int x; public int y; public const int c1 = 5; public const int c2 = c1 + 5; public static const int z=8; //這個寫法錯誤,由於const是靜態常量,可看下面提供c1的IL語言圖片。
//變量能夠在這裏初始化值,可是若是把const放在這裏初始化,編譯會出錯(賦值號左邊必須爲變量、屬性或索引器) public SampleClass(int p1, int p2) { x = p1; y = p2; } } static void Main() { SampleClass mC = new SampleClass(11, 22); Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); Console.WriteLine("c1 = {0}, c2 = {1}",SampleClass.c1, SampleClass.c2); //類型引用 } }
/* Output x = 11, y = 22 c1 = 5, c2 = 10 */
來看下IL語言:
c2和y省略在這裏省略,從上面的圖咱們得出了一個結論:blog
那就是靜態常量,那什麼是靜態常量呢?靜態常量是指編譯器在編譯時候會對常量進行解析,並將常量的值替換成初始化的那個值。即圖中裏面的c1和c2,它們都是在編譯的時候值就肯定下來(c1=5,c2=10),這個相信你們也比較好理解。索引
咱們再來看readonly:圖片
public class ReadOnlyTest { class SampleClass { public readonly int x; public readonly int y = 25; public static readonly int z=12;
//無參構造函數初始化readonly常量 public SampleClass() { y = 24; }
//靜態無參構造函數內初始化static readonly常量 static SampleClass() { z = 23; }
//有參構造函數初始化readonly常量 public SampleClass(int p1, int p2) { x = p1; y = p2; } } static void Main() { //訪問靜態成員 Console.WriteLine(SampleClass.z); //訪問非靜態成員 SampleClass p1 = new SampleClass(11, 21); // OK Console.WriteLine("p1: x={0}, y={1}", p1.x, p1.y); SampleClass p2 = new SampleClass(); Console.WriteLine("p2: x={0}, y={1}", p2.x, p2.y); Console.ReadKey(); } }
/* Output: 23
p1: x=11, y=21
p2: x=0, y=24
*/
一樣的,來看IL語言:
咱們先看下什麼是動態常量:get
動態常量,是指值在運行的那一刻纔得到的,編譯器編譯期間將其標示爲只讀常量,而不用常量的值代替,這樣動態常量沒必要在聲明的時候就初始化,而能夠延遲到構造函數中初始化。
經過const和readonly的代碼咱們能夠得出如下結論:
1.readonly和static readonly定義的常量,指定初始值後(包括在構造函數內指定初始值)將不可更改,可讀不可寫。
2.static readonly常量,若是在構造函數內指定初始值,則必須是靜態無參構造函數,例如z參數的初始化過程。
3.const和static readonly定義的常量是靜態的,只能由類型直接訪問;而readonly定義的常量是非靜態的,只能由實例對象訪問。
1.const默認是靜態的,只能由類型訪問,不能和static同時使用,不然編譯錯誤;readonly默認是非靜態,由實例對象來訪問,能夠顯式使用static定義爲靜態成員。
2.const只能引用在值類型和string類型上,其餘引用類型常量必須聲明爲null,不然以new爲const引用類型常量賦值,編譯器會提示錯誤,緣由是構造函數初始化在運行時,而非編譯時;readonly只讀字段能夠是任意類型,可是對於引用類型字段來講,readonly不能限制對該對象實例成員的讀寫控制。
3.const必須在字段聲明時初始化;而readonly能夠在聲明時,或者構造函數中進行初始化,不一樣的構造函數能夠爲readonly常量實現不一樣的初始值
4.const能夠定義字段和局部變量;而readonly則只能定義字段
5.const因爲是靜態常量因此在編譯時會對常量進行解析,而readonly是動態常量在編譯期間編譯器將其標示爲只讀常量,而不用常量的值代替,這樣就沒必要在聲明的時候就初始化,而能夠延遲到構造函數中初始化
6.從應用角度來看,對於恆定不變且單獨使用的量來講,應該考慮聲明爲const常量,例如性能比,百分比等;而對於可能隨實際運行發生變化的量,應該考慮聲明readonly常量,例如日期或時間,數據庫中的主鍵id等
以上內容但願對一些朋友帶來幫助~~~