[C#] Private Notebook of C#

摘要:[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 類別名稱 [: 父類別名稱]
{
    //定義類別成員..
}