程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Break 、Continue 和ReadOnly、Const和Ref和Out params,readonlyparams

Break 、Continue 和ReadOnly、Const和Ref和Out params,readonlyparams

編輯:C#入門知識

Break 、Continue 和ReadOnly、Const和Ref和Out params,readonlyparams


之前對於Break和Continue;ReadOnly和Const;ref和out,params之類的基礎東東學習過,但是一直沒有仔細去研究到底是怎麼一回事兒,最近在開發中用到了,仔細來做個總結:

1、Break和Continue

//break是跳出整個循環體,不再執行本循環,continue是結束單次循環,繼續下一次循環。 //更多問題 聯系QQ 931697811(夜雨梧桐)

 1  #region Break測試
 2 
 3             Console.WriteLine("========Break========");
 4             int x = 0;
 5             while (x++ < 20)
 6             {
 7                 if (x == 3)
 8                 {
 9                     break;
10                 }
11                 Console.WriteLine("{0}\n",x);
12             } 
13             #endregion
View Code

 

 1  #region Continue測試
 2             Console.WriteLine("========Continue========");
 3             int k = 0;
 4             while (k++ < 10)
 5             {
 6                 if (k == 3)
 7                 {
 8                     continue;
 9                 }
10                 Console.WriteLine("{0}\n",k);
11             } 
12             #endregion
View Code

2、ReadOnly和Const

//有問題:聯系QQ 931697811

  1. const修飾的常量在聲明的時候必須初始化;readonly修飾的常量則可以延遲到構造函數初始化  

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

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

 1  #region ReadOnly
 2         static readonly int A = B * 10;
 3         static readonly int B = 10;
 4 
 5         const int j = k * 10;
 6         const int k = 10;
 7 
 8         static void Main(string[] args)
 9         {
10             Console.WriteLine("===Readonly輸出的值是:===");
11             Console.WriteLine("A is {0}.B is {1}", A, B);
12             Console.WriteLine("===Const輸出的值是:===");
13             Console.WriteLine("j is {0}.k is {1}", j, k);
14             Console.ReadKey();
15         }
16         #endregion
View Code

3、ref和out,params

問題的引出:

現需要通過一個叫Swap的方法交換a,b兩個變量的值。交換前a=1,b=2,斷言:交換後a=2,b=1

 

現編碼如下:

 1  1class Program
 2  2    {
 3  3        static void Main(string[] args)
 4  4        {
 5  5            int a = 1;
 6  6            int b = 2;
 7  7            Console.WriteLine("交換前\ta={0}\tb={1}\t",a,b);
 8  8            Swap(a,b);
 9  9            Console.WriteLine("交換後\ta={0}\tb={1}\t",a,b);
10 10            Console.Read();
11 11        }
12 12        //交換a,b兩個變量的值
13 13        private static void Swap(int a,int b)
14 14        {
15 15            int temp = a;
16 16            a = b;
17 17            b = temp;
18 18            Console.WriteLine("方法內\ta={0}\tb={1}\t",a,b);
19 19        }
20 20    }
View Code

運行結果:

              交換前  a = 1    b = 2

              方法內  a = 2    b = 1

              交換後  a = 1    b = 2

並未達到我們的需求!

原因分析:int類型為值類型,它存在於線程的堆棧中。當調用Swap(a,b)方法時,相當於把a,b的值(即1,2)拷貝一份,然後在方法內交換這兩個值。交換完後,a還是原來的a,b還是原來的b。這就是C#中按值傳遞的原理,傳遞的是變量所對應數據的一個拷貝,而非引用。

 

修改代碼如下即可實現我們想要的結果:

 1 class Program
 2  2    {
 3  3        static void Main(string[] args)
 4  4        {
 5  5            int a = 1;
 6  6            int b = 2;
 7  7            Console.WriteLine("交換前\ta={0}\tb={1}\t",a,b);
 8  8            Swap(ref a,ref b);
 9  9            Console.WriteLine("交換後\ta={0}\tb={1}\t",a,b);
10 10            Console.Read();
11 11        }
12 12        //交換a,b兩個變量的值
13 13        private static void Swap(ref int a, ref int b)
14 14        {
15 15            int temp = a;
16 16            a = b;
17 17            b = temp;
18 18            Console.WriteLine("方法內\ta={0}\tb={1}\t",a,b);
19 19        }
20 20    }
View Code

1 關於重載

   原則:有out|ref關鍵字的方法可以與無out和ref關鍵字的方法構成重載;但如想在out和ref間重載,編譯器將提示:不能定義僅在ref和out的上的方法重載

2 關於調用前初始值

   原則:ref作為參數的函數在調用前,實參必須賦初始值。否則編譯器將提示:使用了未賦值的局部變量;

          out作為參數的函數在調用前,實參可以不賦初始值。

3 關於在函數內,引入的參數初始值問題

   原則:在被調用函數內,out引入的參數在返回前至少賦值一次,否則編譯器將提示:使用了未賦值的out參數;

          在被調用函數內,ref引入的參數在返回前不必為其賦初值。

總結:C#中的ref和out提供了值類型按引用進行傳遞的解決方案,當然引用類型也可以用ref和out修飾,但這樣已經失去了意義。因為引用數據類型本來就是傳遞的引用本身而非值的拷貝。ref和out關鍵字將告訴編譯器,現在傳遞的是參數的地址而不是參數本身,這和引用類型默認的傳遞方式是一樣的。同時,編譯器不允許out和ref之間構成重載,又充分說明out和ref的區別僅是編譯器角度的,他們生成的IL代碼是一樣的。有人或許疑問,和我剛開始學習的時候一樣的疑惑:值類型在托管堆中不會分配內存,為什麼可以按地址進行傳遞呢?值類型雖然活在線程的堆棧中,它本身代表的就是數據本身(而區別於引用數據類型本身不代表數據而是指向一個內存引用),但是值類型也有它自己的地址,即指針,現在用ref和out修飾後,傳遞的就是這個指針,所以可以實現修改後a,b的值真正的交換。這就是ref和out給我們帶來的好處。

關於更多如This,Base等下次再分享

 


const與readonly的異同?

const 的概念就是一個包含不能修改的值的變量。
常數表達式是在編譯時可被完全計算的表達式。因此不能從一個變量中提取的值來初始化常量。
如果 const int a = b+1;b是一個變量,顯然不能再編譯時就計算出結果,所以常量是不可以用變量來初始化的。

readonly 允許把一個字段設置成常量,但可以執行一些運算,可以確定它的初始值。
因為 readonly 是在計算時執行的,當然它可以用某些變量初始化。
readonly 是實例成員,所以不同的實例可以有不同的常量值,這使readonly更靈活。

readonly 關鍵字與 const 關鍵字不同。

1. const 字段只能在該字段的聲明中初始化。
readonly 字段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 字段可能具有不同的值。
2. const 字段是編譯時常數,而 readonly 字段可用於運行時常數。
3. const 默認就是靜態的,而 readonly 如果設置成靜態的就必須顯示聲明。
4.const 對於引用類型的常數,可能的值只能是 string 和 null。
readonly可以是任何類型

* 需要注意的一個問題是:

對於一個 readonly 的 Reference 類型,只是被限定不能進行賦值(寫)操作而已。而對其成員的讀寫仍然是不受限制的。

public static readonly Class1 my = new Class1();

my.SomeProperty = 10; //正常
my = new Class1(); //出錯,該對象是只讀的

但是,如果上例中的 Class1 不是一個 Class 而是一個 struct,那麼後面的兩個語句就都會出錯。

static readonly:

Java 中 static 是當載入一個類時執行一次的。

C#中是怎麼執行的,我沒有查到。很奇怪幾乎每本java的書都會說static的問題,C#的往往只說怎麼用,但是應該是在main函數調用之前初始化,所以static readonly也是運行時的,可以用變量付值,如:

private static readonly string path = System.Windows.Forms.Application.StartupPath + “aaa”;
 

c#中const與readonly不同

const 的概念就是一個包含不能修改的值的變量。
常數表達式是在編譯時可被完全計算的表達式。因此不能從一個變量中提取的值來初始化常量。
如果 const int a = b+1;b是一個變量,顯然不能再編譯時就計算出結果,所以常量是不可以用變量來初始化的。

readonly 允許把一個字段設置成常量,但可以執行一些運算,可以確定它的初始值。
因為 readonly 是在計算時執行的,當然它可以用某些變量初始化。
readonly 是實例成員,所以不同的實例可以有不同的常量值,這使readonly更靈活。

readonly 關鍵字與 const 關鍵字不同。

1. const 字段只能在該字段的聲明中初始化。
readonly 字段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 字段可能具有不同的值。
2. const 字段是編譯時常數,而 readonly 字段可用於運行時常數。
3. const 默認就是靜態的,而 readonly 如果設置成靜態的就必須顯示聲明。
4.const 對於引用類型的常數,可能的值只能是 string 和 null。
readonly可以是任何類型

總結
const只能在初期就使用常量初始化好。對於每一次編譯後的結果,const的值是固定的,而readonly的值是可以在運行的時候才確定值的~~
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved