摘要:[C#] Private Notebook of C#
內容轉自 http://forums.wasabistudio.ca/viewtopic.php?f=172&t=22681
Code Region
方便user在VS中展開及收合程式碼區域。
#region "程式區域註解"
//程式區域..
#ednregion
Namespace
用來管理class。
預設為專案名稱。
namespace 命名空間名稱
{
//定義類別..
}
Inheritance
和Java一樣,只能宣告繼承一個父類別。
繼承語法和C++一樣。
[存取修飾子] class 類別名稱 : 父類別名稱
{
//定義類別成員..
}
Property
一般屬性名稱會和對應的欄位名稱相同,但第一個字母大寫。
屬性預設的存取修飾子為public。
範例(1)
class Test
{
private int a1;
public int A1
{
get { return this.a1; }
set { this.a1 = value; }
}
public int a2;
private int A2
{
get { return this.a2; }
set { this.a2 = value; }
}
}
value是一個關鍵字,推測的運作原理:
get:int A1 = this.a1; 外部 = A1;
set:int A1 = var value; a1 = A1;
get{}和set{}都不能重複。
屬性的資料型別可以任意宣告,不過必須可以安全的get和set而不發生溢位,
所以原則上會和對應的欄位用相同的資料型別。欄位可以宣告為public,外部程式可以直接存取該欄位值(不過這樣不符合資料封裝的概念);
屬性也可以宣告為private,只有類別內的成員可以存取該屬性值(不過這樣沒啥意義)。
範例(2)
class Test
{
static private int a1;
static public int A1
{
get { return a1; }
set { a1 = value; }
}
static private int a2;
public int A2
{
get { return a2; }
set { a2 = value; }
}
private int a3;
static public int A3
{
get { return new Test().a3; }
set { new Test().a3 = value; }
}
}
如果欄位宣告為static,對應的屬性最好也宣告為static,並直接以類別名稱存取:Test.A1。
如果欄位和對應的屬性一個為static一個不是,那會變得很無言,
欄位為static但屬性不是:外部存取屬性時需先new Test物件,new Test().A2
屬性為static但欄位不是:需在get{}和set{}內new Test物件。靜態成員(field或method)均不能以this存取,this代表的是以該類別new出來的instance。
Constructor
宣告constructor時,可以用this呼叫另一個constructor,或用base呼叫父類別的constructor。
範例
class Test
{
private int a, b, c;
public Test(int a, int b, int c) : base()
{
this.a = a;
this.b = b;
this.c = c;
}
public Test() : this(0, 0, 0) { }
}
class Test2 : Test
{
private int x, y, z;
public Test2(int x, int y, int z) : base(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Test2() : this(0, 0, 0) {}
}
base()不能使用this當引數,因為這個時候this的instance還沒new出來。
Access Modifiers
private
只能在自己類別中存取。protected
只能在自己類別與子類別中存取。internal
只能在自己類別與專案(組件)中其他的類別存取。protected internal
只能在自己類別、子類別與專案(組件)中其他的類別存取。pulbic
沒有任何存取限制。
Nullable Variables
宣告:
資料型別? 變數名稱;
指定:
變數A = 可為Null的變數B ?? 當變數B為Null的替代值;
Implicitly Typed Local Variables
var 變數名稱 = 值;
var 變數名稱 = new [] {成員0, 成員1, 成員3, ...};
foreach (var 變數名稱 in 陣列/集合變數) { ... }
var 變數名稱 = new { 屬性名稱1 = 值1, 屬性名稱2 = 值2, ...};
Enumeration
enum 列舉常數名稱 [: 整數型別(預設為int)]
{
常數1 [=值(預設從0依序開始)];
常數2 [=值];
...
}
列舉常數名稱 變數名稱 = 列舉常數名稱.常數n
Comparison Operator
C#的 String == String 並不像Java一樣用來判斷兩個參照是否指向同一個物,
而是判別兩個字串的內容是否相同,與Java的String.equal()功能一樣。
Switch
和Java不同,case的值可以為String,比較方式和String==String一樣,不過不建議case String。
和Java不同,每個case包括default都需要break或goto,continue則不能用在switch之中。
switch (變數或運算式)
{
case 值1:
[敘述...]
break/goto case 值n;
case 值2:
[敘述...]
break/goto case 值n;
case 值3:
[敘述...]
break/goto case 值n;
...
default:
[敘述...]
break/goto case 值n;
}
Foreach
foreach (資料型別 變數 in 集合或陣列)
{
//敘述...
}
Arrays
C#的陣列只能這樣宣告:int[] array = new int[100];
不能像Java或C宣告成:int array[] = new int[100];陣列可透過Length屬性取得長度(Java是小寫)。
多維陣列(1)
多維陣列第一種宣告方式(矩陣):
int[,] ar1 = new int[3, 5]; int[,] ar2 = { { 1, 2, 3, 4, 5 }, { 1, 2, 3, 4, 5 }, { 1, 2, 3, 4, 5 } }; int[,,] ar3 = new int[3, 5, 2]; int[,,] ar4 = { { { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 } }, { { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 } }, { { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 } } };
不過這種宣告方式只能取得陣列總長度(ex: ar1.Length),無法取得各成員陣列的長度。
此外若用foreacn迴圈探訪這種宣告方式的陣列(ex: foreach (int temp in ar1)),
會從頭到尾探訪每個成員,沒辦法各別探訪某個成員陣列。
多維陣列(2)
多維陣列第二種宣告方式,和Java差不多,但不能直接在宣告時配置(ex: int[][] ar = new int[3][5]):
/* 宣告不規則多為陣列 */ int[][] ar = new int[3][]; /* 配置成員陣列 */ for (int i = 0; i < ar.Length; i++) ar1[i] = new int[(i+1)*10]; /* 取得陣列及成員陣列的長度 */ Console.WriteLine("{0}", ar.Length); Console.WriteLine("{0}", ar[0].Length); Console.WriteLine("{0}", ar[1].Length); Console.WriteLine("{0}", ar[2].Length); /* 設定成員陣列 */ for (int i = 0; i < ar.Length; i++) { for (int j = 0; j < ar[i].Length; j++) ar[i][j] = j+1; } /* 迴圈走訪陣列 */ foreach (int[] TEMP in ar) { foreach (int temp in TEMP) { Console.WriteLine("{0}", temp); } }
兩種方式混搭著用
/* 宣告 */
int[][,] ar1 = new int[3][,];
int[,][] ar2 = new int[3, 5][];
/* 配置 */
for (int i=0; i<ar1.Length; i++)
ar1[i] = new int[5,2];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
ar2[i, j] = new int[2];
}
/* 設定 */
for (int i = 0; i < ar1.Length; i++)
{
for (int j = 0; j < 5; j++)
{
for (int k = 0; k < 2; k++)
ar1[i][j, k] = 999;
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
for (int k = 0; k < ar2[i, j].Length; k++)
ar2[i, j][k] = 999;
}
}
/* 走訪 */
foreach (int[,] TEMP in ar1)
{
foreach (int temp in TEMP)
{
Console.WriteLine("{0}", temp);
}
}
foreach (int[] TEMP in ar2)
{
foreach (int temp in TEMP)
{
Console.WriteLine("{0}", temp);
}
}
Partical Class
讓user將一個類別寫在不同原始檔中,編譯時會合併成一個類別檔。
[存取修飾子] partial class 類別名稱 [: 父類別名稱]
{
//定義類別成員..
}
[存取修飾子] partial class 類別名稱 [: 父類別名稱]
{
//定義類別成員..
}