對於readonly和const,不少人沒法具體區分,不清楚它們的具體使用場合;如今咱們分析它們之間的區別和使用場合。ide
const是一個編譯期常量;const只能用於修飾基元類型、枚舉類型或者字符串類型,具備侷限性;函數
由於const是編譯期常量,因此const自然就是static的,不用手動的爲其增長static修飾符,例如:spa
static const int ConstValue = 100;
編譯時,將會提示「常量 ConstValue不能標記爲static」;指針
const最大的優勢在於 「效率」,這也是使用const的理由,之因此說const效率高,是由於它在通過編譯器編譯後,咱們在代碼中引用const變量的地方會用const變量所對應的實際的值來代替,例如:code
Console.WriteLine(ConstValue);
其實代碼生成的IL代碼則爲blog
Console。WriteLine(100);
此時程序將再也不經過變量來尋找對應的值。字符串
然而readonly是一個運行時常量,而且readonly能夠修飾任何類型,沒有限制,其賦值行爲發生在運行時,readonly的所有意義在於,它在運行時第一次被賦值後將不能夠改變,固然了,這個能夠分爲兩個意思get
1.對於值類型變量,值自己不可改變編譯器
2.對於引用類型變量,引用自己不可改變(指針不可改變)string
先說說值類型,例如:
class Employee { public readonly int ReadOnlyNumber; public Employee(int value) { ReadOnlyNumber = value; } }
Employee的實例ReadOnlyNumber在構造方法中被賦值,以後將不可改變,例如
Employee emp = new Employee(100); emp.ReadOnlyNumber = 20;
此代碼將沒法經過編譯,提示「沒法對只讀字段賦值(構造函數或者變量初始值指定項中除外)」;
針對於引用類型變量,咱們能夠作以下的修改
class Boss { public string Name { get; set; } } class Employee2 { public readonly Boss ReadOnlyBoss; public Employee2(Boss value) { ReadOnlyBoss = value; } }
Employee2的ReadOnlyBoss是一個引用類型變量,在其被賦值後,變量不能再指向任何其餘的Boss實例;例如
Employee2 emp2 = new Employee2(new Boss() { Name="Witt"}); emp2.ReadOnlyBoss = new Boss() { Name = "Witt2" };
這段代碼將沒法編譯成功,由於ReadOnlyBoss不能在賦值後再指向任何其餘的實例。
可是呢,以前咱們說過,引用自己不可改變,可是引用所指向的實例的屬性值卻能夠隨意修改,例以下面這段代碼將能夠經過
Employee2 emp2 = new Employee2(new Boss() { Name="Witt"}); //emp2.ReadOnlyBoss = new Boss() { Name = "Witt2" }; emp2.ReadOnlyBoss.Name = "Witt2";
readonly所表明的運行時含義有一個重要的做用,就是能夠爲每個類的實例指定一個readonly的變量,咱們之前面的Employee來舉例說明;
Employee e1 = new Employee(10); Employee e2 = new Employee(100); Employee e3 = new Employee(200); Employee e4 = new Employee(300); Employee e5 = new Employee(400);
在這裏,每一個實例都生成了本身的readonly變量,這也就是readonly的優勢。
好了,說了這麼多,相信你們也都明白了,const的優勢在於效率,但卻沒有readonly靈活,在程序對效率的要求並不高時(效率的地位不高),readonly則成爲你更好的選擇,由於readonly沒有更多的靈活性。
如今說一下注意點,以前我說過readonly在賦值以後將不能被再次賦值,這是錯誤的,下面這個例子將很好的說明這一點
class Employee { public readonly int ReadOnlyNumber = 50; public Employee(int value) { ReadOnlyNumber = value; ReadOnlyNumber += 20; ReadOnlyNumber *= 2; } }
ReadOnlyNumber在初始化器中被賦值爲50,後來,在構造中又被屢次賦值;實際上,咱們能夠將初始化器理解成構造方法的一部分,在構造方法中,咱們確實能夠屢次對ReadOnlyNumber賦值。