C#速成(之四) (轉)

amyz發表於2007-11-25
C#速成(之四) (轉)[@more@]

-------------------

裝箱和拆箱操作(Boxing/Unboxing)

-------------------

:namespace prefix = o ns = "urn:schemas--com::office" />

的裝箱思想是全新的。上面提到過所有的資料型別,不論內建或自定義,全都從名稱空間System的一個基類派生出來。因此把基本的或者原始型別轉換成object型別被稱做裝箱,反之,這種方式的逆操作被稱為拆箱。

示例:

class Test

{

  static void Main()

  {

  int myInt = 12;

  object obj = myInt ;  // 裝箱

  int myInt2 = (int) obj;  // 拆箱

  }

}

示例展示了裝箱和拆箱操作。一個整型值轉換成object型別,然後又轉換回整型。當一個值型別的變數需要轉換成引用型別時,一個object的箱子會被分配容納這個值的空間,這個值會被複制進這個箱子。拆箱與此相反,一個object箱子中的資料被轉換成它的原始值型別時,這個值將被從箱中複製到適當的位置。

-------------------

方法引數

-------------------

C#中有三種型別的引數:

值引數/輸入型引數

引用型引數/輸入輸出型引數

Out引數

如果你有COM介面和它的引數型別的概念,你會很容易理解C#引數型別。

值引數/輸入型引數

值概念與C++相同。所要傳遞的值會被複制到一個位置上並被傳遞給。

示例:

SetDay(5);

...

void SetDay(int day)

{

  ....

}

引用型引數/輸入輸出引數

C#中的引用引數既不是C++中的指標也不是引用運算子(&)來傳遞的。C#的引用型引數減少了出錯的可能。引用型引數也被稱作輸入輸出引數,因為你傳遞了一個引用地址,因此你可以從函式中傳遞一個輸入值並且可以獲得一個輸出值。

你不能把一個未經初始化的引用型引數傳遞給函式。C#用ref這個關鍵字來宣告引用型引數。當你傳遞一個變數給函式要求的引用引數時必須使用一個ref關鍵字說明。

示例:

  int a= 5;

  FunctionA(ref a);  // 要用ref宣告變數,否則你會得到

   // 一個編譯錯誤

  Console.WriteLine(a);  // 指向地址的值為20

  void FunctionA(ref int Val)

  {

  int x= Val;

  Val = x* 4;

  }

Out引數

Out型引數僅僅從函式當中返回一個值。不要求有輸入值。C#用關鍵字out來描宣告這個引數

示例:

  int Val;

  GetNodeValue(Val);

  bool GetNodeValue(out int Val)

  {

  Val = value;

  return true;

  }

可變數量的引數和陣列

陣列在C#當中是透過關鍵字params來描述傳遞的。作為陣列型別的變數,你能傳遞任意數量的元素。從下面示例中你可以理解的更好。

示例:

  void Func(params int[] array)

  {

  Console.WriteLine("number of elements {0}",array.Length);

  }

  Func();  // prints 0

  Func(5);  // prints 1

  Func(7,9);  // prints 2

  Func(new int[] {3,8,10});  // prints 3

  int[] array = new int[8] {1,3,4,5,5,6,7,5};

  Func(array);  // prints 8

-------------------

運算子和

-------------------

運算子和表示式概念與C++完全相同。但是一些新的有用的運算子被填加了進來。我將在這裡討論其中的某些部分。

is 運算子

is 運算子被用於檢查運算元的型別是否相同或者是否可以轉換。is 運算子在多型環境下特別有用。它有兩個運算元,運算結果是一個布林型。看這個示例:

void function(object param)

{

  if(param is ClassA)

  //do something

  else if(param is MyStruct)

  //do something

  }

}

as 運算子

as 運算子檢查運算元的型別是否可被轉換或者是否相等(這些 as透過 is 運算子來完成。如果結果是可轉換的,則結果將被轉換或者被裝箱,成object(關於as運算子進行裝箱成目標型別的操作請看前面的裝箱/拆箱操作)。如果不可轉換或者裝箱,則返回值是null。瞧一瞧下面的例子我們會更好地理解這個概念。

Shape shp = new Shape();

Vehicle veh = shp as Vehicle;  // 結果是null, 型別不可轉換

Circle cir = new Circle();

Shape shp = cir;

Circle cir2 = shp as Circle;  //會被轉換

object[] objects = new object[2];

objects[0] = "Aisha";

object[1] = new Shape();

string str;

for(int i=0; i&< objects.Length; i++)

{

  str = objects[i] as string;

  if(str == null)

  Console.WriteLine("can not be converted");

  else

  Console.WriteLine("{0}",str);

}

輸出:

Aisha

can not be converted

-------------------

語句

-------------------

除了對某些新增語句和對某些語句的修改以外,C#語句與C++非常相象。

下面是新增的語句:

foreach

用於迴圈依次訪問集合元素,比如象陣列等。

示例:

  foreach (string s in array)

  Console.WriteLine(s);

lock

用於鎖住程式碼塊,使執行緒在臨界爭區內,別的執行緒無法進入鎖定的臨界區。

checked/unchecked

用於數值運算中的檢測。

示例:

int x = Int32.MaxValue; x++;  // 溢位檢測

{

x++;   // 異常

}

unchecked

{

x++;  // 溢位}

}

下面的語句在C#當中已經被修改:

Switch

一個case語句後,流程不允許跳到下一個相鄰case語句。這在C++當中是被允許的。

示例:

int var = 100;

switch (var)

{

  case 100: Console.WriteLine("");

  // 沒有break語句

   case 200: Console.WriteLine(""); break;

}

C++編譯後的輸出:

 

C#下,編譯時會報錯:

error CS0163: Control cannot fall through from one case label

('case 100:') to another

但是你仍然能做C++類似的事

switch (var)

{

  case 100:

  case 200: Console.WriteLine("100 or 200");

  break;

}

你也可以常數變數作為case 的值:

示例:

const string WeekEnd  = "Sunday";

const string WeekDay1 = "Monday";

....

string WeekDay = Console.ReadLine();

switch (WeekDay )

{

case WeekEnd: Console.WriteLine("It's weekend!!"); break;

case WeekDay1: Console.WriteLine("It's Monday"); break;

}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-984621/,如需轉載,請註明出處,否則將追究法律責任。

相關文章