Programming C#.Classes and Objects.只读字段
只讀字段
當(dāng)字段聲明中含有?readonly?修飾符時(shí),該聲明所引入的字段為只讀字段。給只讀字段的直接賦值只能作為聲明的組成部分出現(xiàn),或在同一類中的實(shí)例構(gòu)造函數(shù)或靜態(tài)構(gòu)造函數(shù)中出現(xiàn)。(在這些上下文中,只讀字段可以被多次賦值。)準(zhǔn)確地說,只在下列上下文中允許對(duì)?readonly?字段進(jìn)行直接賦值:
- 在用于引入該字段的變量聲明符中(通過添加一個(gè)變量初始值設(shè)定項(xiàng))。
- 對(duì)于實(shí)例字段,在包含字段聲明的類的實(shí)例構(gòu)造函數(shù)中;對(duì)于靜態(tài)字段,在包含字段聲明的類的靜態(tài)構(gòu)造函數(shù)中。也只有在這些上下文中,將?readonly?字段作為?out?或?ref?參數(shù)傳遞才有效。
在其他任何上下文中,試圖對(duì)?readonly?字段進(jìn)行賦值或?qū)⑺鳛?out?或?ref?參數(shù)傳遞都會(huì)導(dǎo)致一個(gè)編譯時(shí)錯(cuò)誤。
?
C#常量數(shù)據(jù)與只讀字段
常量數(shù)據(jù)
C#提供了const關(guān)鍵字來定義常量,如果我們要為應(yīng)用程序定義邏輯上和某個(gè)類或結(jié)構(gòu)相關(guān)的一組已知值的話,就非常有用。
假如我們創(chuàng)建一個(gè)MyMathClass的工具類,且需要定義一個(gè)PI值(假如是3.14),如果不希望別的開發(fā)者改變PI值,可以使用如下常量定義PI值:
1 class MyMathClass 2 { 3 //定義為常量數(shù)據(jù) 4 public const double PI=3.14; 5 } 6 class Program 7 { 8 public static void Main(string[] args) 9 { 10 //注意:因?yàn)槌A繑?shù)據(jù)是隱式靜態(tài)的,所以只能直接在類級(jí)別上調(diào)用(MyMathClass.PI)。 11 Console.WriteLine("PI值是:{0}",MyMathClass.PI); 12 13 //錯(cuò)誤!常量數(shù)據(jù)不能被修改。 14 MyMathClass.PI=3.15; 15 Console.ReadLine(); 16 } 17 }注意:定義常量時(shí)必須為常量指定初始值,常量一旦定義就不能修改了。
1 class MyMathClass 2 { 3 //嘗試再構(gòu)造函數(shù)中給常量賦值 4 public const double PI; 5 public MyMathClass() 6 { 7 //錯(cuò)誤! 8 PI=3.14; 9 } 10 }在編譯時(shí)必須知道常量的值!
只讀字段
和常量密切聯(lián)系的概念是只讀字段(不要和只讀屬性混淆哦,只讀屬性指只有g(shù)et塊的屬性)。和常量相似,只讀字段不能在賦值后改變。然而,和常量不同,賦值給只讀字段可以在運(yùn)行時(shí)決定。因此在構(gòu)造函數(shù)作用域范圍內(nèi)給只讀字段賦值是合法的(其他地方不行!)。
1 class MyMathClass 2 { 3 //可以構(gòu)造函數(shù)中為只讀字段賦值,其他地方不行! 4 public readonly double PI; 5 public MyMathClass() 6 { 7 PI=3.14; 8 } 9 public void ChangePI() 10 { 11 //錯(cuò)誤! 12 PI=3.14; 13 } 14 }另:只讀字段不是隱式靜態(tài)的,要定義靜態(tài)只讀字段就需要使用static關(guān)鍵字了。
問題:請(qǐng)敘述const與readonly的區(qū)別。
?? ?const 關(guān)鍵字用于修改字段或局部變量的聲明。它指定字段或局部變量的值不能被修改。常數(shù)聲明引入給定類型的一個(gè)或多個(gè)常數(shù),開心哦。const數(shù)據(jù)成員的聲明式必須包含初值,且初值必須是一個(gè)常量表達(dá)式。因?yàn)樗窃诰幾g時(shí)就需要完全評(píng)估。const成員可以使用另一個(gè)const成員來初始化,前提是兩者之間沒有循環(huán)依賴。readonly在運(yùn)行期評(píng)估賦值,使我們得以在確保“只讀訪問”的前提下,把object的初始化動(dòng)作推遲到運(yùn)行期進(jìn)行。
?? ?readonly 關(guān)鍵字與 const 關(guān)鍵字不同: const 字段只能在該字段的聲明中初始化。readonly 字段可以在聲明或構(gòu)造函數(shù)中初始化。因此,根據(jù)所使用的構(gòu)造函數(shù),readonly 字段可能具有不同的值。另外,const 字段是編譯時(shí)常數(shù),而 readonly 字段可用于運(yùn)行時(shí)常數(shù)。readonly 只能在聲明時(shí)或者構(gòu)造函數(shù)里面初始化。
readonly的作用就是:一些變量,不允許別人修改,但是在聲明的時(shí)候還不能對(duì)其賦值,所以不能用const常亮。這時(shí)可以用readonly關(guān)鍵字,在類的構(gòu)造函數(shù)中對(duì)這些變量賦值。
枚舉與常量需要注意的一個(gè)問題
.net中枚舉其實(shí)就是數(shù)值型的常量,與const類似。當(dāng)我們?cè)诖a中使用枚舉代表的數(shù)值或者常量時(shí),編譯器其實(shí)是將該值直接寫過來,而不會(huì)在運(yùn)行的時(shí)候去讀取該值。下面是一個(gè)例子:
我們想建立一個(gè)類庫項(xiàng)目,名稱叫ClassLibrary1,再建立一個(gè)控制臺(tái)項(xiàng)目,名稱叫ConsoleApplication2,結(jié)構(gòu)如下:
ClassLibrary1項(xiàng)目中Class1中的代碼是:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ClassLibrary1 7 { 8 public class MyClass 9 { 10 public static string str1 = "str1"; 11 public const string str2 = "str2"; 12 } 13 14 public enum MyEnum 15 { 16 One = 1, 17 Two = 2, 18 Three = 3 19 } 20 }定義了一個(gè)枚舉以及一個(gè)靜態(tài)字段、一個(gè)常量字段。
ConsoleApplication2項(xiàng)目引用A項(xiàng)目,代碼如下:
1 using System; 2 using ClassLibrary1; 3 4 class Program 5 { 6 public static void Main(string[] args) 7 { 8 Console.WriteLine((int)MyEnum.One); 9 Console.WriteLine(MyEnum.One.ToString()); 10 11 Console.WriteLine(MyClass.str1); 12 Console.WriteLine(MyClass.str2); 13 14 Console.ReadKey(); 15 } 16 }我們來看看Program類用Reflector工具反編譯后的樣子:
public class MyClass {// Fieldspublic static string str1;public const string str2 = "str2";// Methodsstatic MyClass();public MyClass(); }注意:這里自動(dòng)的添加了兩個(gè)構(gòu)造函數(shù),一個(gè)靜態(tài)一個(gè)非靜態(tài)。 1 public static void Main(string[] args) 2 { 3 Console.WriteLine(1); 4 Console.WriteLine(MyEnum.One.ToString()); 5 Console.WriteLine(MyClass.str1); 6 Console.WriteLine("str2"); 7 Console.ReadKey(); 8 }編譯器將(int)MyEnum.One的值與常量字段str2直接硬編碼寫到代碼中,而不是在運(yùn)行期再去讀取。
這樣處理的后果是:如果你修改了A項(xiàng)目中的枚舉的排列順序或者枚舉對(duì)應(yīng)的值(或者改變了常量字段str2的值),比如將MyEnum.One的值2,同時(shí)不重新編譯Test項(xiàng)目,那樣運(yùn)行結(jié)果還是不會(huì)變的。
?
轉(zhuǎn)載于:https://www.cnblogs.com/stemon/p/4087881.html
總結(jié)
以上是生活随笔為你收集整理的Programming C#.Classes and Objects.只读字段的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Axure 8.0/9.0 注册码 激活
- 下一篇: C#连接数据库SQL(2005)