1. 程式人生 > >【程式語言】在Unity3D中的C#程式設計初級

【程式語言】在Unity3D中的C#程式設計初級

一、前言

這篇文章主要是給零基礎想要Unity入門的關於C#程式設計的一些意見

二、參考文章

三、正文

1、支援Unity3D的程式語言

  • C#、JavaScript、UnityScript
    先說C#與JavaScript,因為JavaScript是動態的,肯定不如編譯的C#好,但是JavaScript更快捷一點, JavaScript適合個人開發,敏捷快速。c#適合公司開發,規範嚴謹。
  • 然後說說這個C#和Unity內建的UnityScript
    UnityScript脫胎於.Net平臺的第三方語言Boo,差距可能是全方位,立體式的。社群支援,程式碼維護,甚至是編譯出來的CIL程式碼質量都可能有很大的差距。另外從Unity5.0版本開始就會停止對Boo的文件支援。同時消失的還有從選單建立Boo指令碼的選項“Create Boo Script”。從U3D團隊對Boo的態度,也可以窺見和Boo聯絡密切的UnityScript未來的走勢。

2、程式設計工具(IDE)

  • Visual Studio 全系列
  • Visual Studio Code
  • Xamarin Studio
    這個主要是在Mac上使用的IDE,因為在Mac上不能使用VS,MonoDevelop也不能輸入中文,就挺難受的,就可以使用XamarinStudio,關於這個IDE使用可以參考這篇文章。http://www.xuanyusong.com/archives/3545
  • MonoDevelop
    Unity3D內建的編輯器,操作感覺一般,但是勝在方便,在安裝Unity3D的時候就可以一起安裝了,不用另外安裝IDE了

3、建立C#程式碼

  1. 在工程目錄下右鍵點選,選擇Create->C# Script
    這裡寫圖片描述
  2. 在任意物件上,點選Add Component->New Script
    這裡寫圖片描述
    這個是建立成功後的初始指令碼的樣子
    這裡寫圖片描述

4、場景的儲存和指令碼的儲存

  • 快捷鍵F2 點選場景名或者指令碼名字可以重新命名
  • 快捷鍵Ctrl+S 快速儲存場景或者儲存指令碼
  • 狀態列中顯示“*”號的都是未儲存的
    這裡寫圖片描述
  • 編輯器意外奔潰,場景未來得及儲存?
    這時可以開啟工程目錄,找到/Temp/_Backupscenes/資料夾,可以看到有後綴名為.backup的檔案,將該檔案的字尾名改為.unity拖拽到專案檢視,即可還原編輯器崩潰前的場景。
    這裡寫圖片描述

5、關於日誌輸出(指控制輸出,其中Log有三類:正常、警告、錯誤輸出)

  • print
    是MonoBehaviour的一個成員,必須繼承MonoBehaviour才能使用,通過反編譯可以看到print的方法為
public static void print(object message)
{
    Debug.Log(message);
}

說明print方法還是通過Debug.Log實現的,print就是Debug.Log的一個簡單封裝。

  • Debug.Log
    輸出log資訊,可以在執行的時候檢視關鍵資料的變化

  • Debug.LogWarning
    輸出警告資訊

  • Debug.LogError
    輸出錯誤資訊

這裡寫圖片描述
這裡寫圖片描述

6、變數與常量

因為兩個比較相似,就放一塊說

  • 變數
    一個變數只不過是一個供程式操作的儲存區的名字。在 C# 中,每個變數都有一個特定的型別,型別決定了變數的記憶體大小和佈局。範圍內的值可以儲存在記憶體中,可以對變數進行一系列操作。

  • 常量
    常量是固定值,程式執行期間不會改變。常量可以是任何基本資料型別,比如整數常量、浮點常量、字元常量或者字串常量,還有列舉常量。
    常量可以被當作常規的變數,只是它們的值在定義後不能被修改。

  • 變數的型別

型別 舉例
整數型別 sbyte、byte、short、ushort、int、uint、long、ulong 和 char
浮點型 float 和 double
十進位制型別 decimal
布林型別 true 或 false 值,指定的值
空型別 可為空值的資料型別
其他變數型別 列舉enum,引用型別變數class,結構體型別struct
  • 變數的定義
int i, j, k;
char c, ch;
float f, salary;
double d;
  • 變數的初始化
int d = 3, f = 5;    /* 初始化 d 和 f. */
byte z = 22;         /* 初始化 z. */
double pi = 3.14159; /* 宣告 pi 的近似值 */
char x = 'x';        /* 變數 x 的值為 'x' */

例項

namespace VariableDefinition
{
    class Program
    {
        static void Main(string[] args)
        {
            short a;
            int b ;
            double c;

            /* 實際初始化 */
            a = 10;
            b = 20;
            c = a + b;
            Console.WriteLine("a = {0}, b = {1}, c = {2}", a, b, c);
            Console.ReadLine();
        }
    }
}

編譯執行結果:

a = 10, b = 20, c = 30
  • 常量的定義
 const double pi = 3.14159; // 常量宣告
  • 常量的型別
整數常量

整數常量可以是十進位制、八進位制或十六進位制的常量。字首指定基數:0x 或 0X 表示十六進位制,0 表示八進位制,沒有字首則表示十進位制。

整數常量也可以有後綴,可以是 U 和 L 的組合,其中,U 和 L 分別表示 unsigned 和 long。字尾可以是大寫或者小寫,多個字尾以任意順序進行組合。

212         /* 合法 */
215u        /* 合法 */
0xFeeL      /* 合法 */
078         /* 非法:8 不是一個八進位制數字 */
032UU       /* 非法:不能重複字尾 */
85         /* 十進位制 */
0213       /* 八進位制 */
0x4b       /* 十六進位制 */
30         /* int */
30u        /* 無符號 int */
30l        /* long */
30ul       /* 無符號 long */
浮點常量

一個浮點常量是由整數部分、小數點、小數部分和指數部分組成。您可以使用小數形式或者指數形式來表示浮點常量。
這裡有一些浮點常量的例項:

3.14159       /* 合法 */
314159E-5L    /* 合法 */
510E          /* 非法:不完全指數 */
210f          /* 非法:沒有小數或指數 */
.e55          /* 非法:缺少整數或小數 */

使用小數形式表示時,必須包含小數點、指數或同時包含兩者。使用指數形式表示時,必須包含整數部分、小數部分或同時包含兩者。有符號的指數是用 e 或 E 表示的。

字元常量

字元常量是括在單引號裡,例如,’x’,且可儲存在一個簡單的字元型別變數中。一個字元常量可以是一個普通字元(例如 ‘x’)、一個轉義序列(例如 ‘\t’)或者一個通用字元(例如 ‘\u02C0’)。

在 C# 中有一些特定的字元,當它們的前面帶有反斜槓時有特殊的意義,可用於表示換行符(\n)或製表符 tab(\t)。在這裡,列出一些轉義序列碼:

轉義序列含義
\\\ 字元
\’’ 字元
\”” 字元
\?? 字元
\aAlert 或 bell
\b退格鍵(Backspace)
\f換頁符(Form feed)
\n換行符(Newline)
\r回車
\t水平製表符 tab
\v垂直製表符 tab
\ooo一到三位的八進位制數
\xhh …一個或多個數字的十六進位制數

例項:

namespace EscapeChar
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello\tWorld\n\n");
            Console.ReadLine();
        }
    }
}

編譯執行結果:

Hello   World
字串常量

字串常量是括在雙引號 “” 裡,或者是括在 @”” 裡。字串常量包含的字元與字元常量相似,可以是:普通字元、轉義序列和通用字元

使用字串常量時,可以把一個很長的行拆成多個行,可以使用空格分隔各個部分。

這裡是一些字串常量的例項。下面所列的各種形式表示相同的字串。

string a = "hello, world";                  // hello, world
string b = @"hello, world";               // hello, world
string c = "hello \t world";               // hello     world
string d = @"hello \t world";               // hello \t world
string e = "Joe said \"Hello\" to me";      // Joe said "Hello" to me
string f = @"Joe said ""Hello"" to me";   // Joe said "Hello" to me
string g = "\\\\server\\share\\file.txt";   // \\server\share\file.txt
string h = @"\\server\share\file.txt";      // \\server\share\file.txt
string i = "one\r\ntwo\r\nthree";
string j = @"one
two
three";

例項:

using System;

namespace DeclaringConstants
{
    class Program
    {
        static void Main(string[] args)
        {
            const double pi = 3.14159; // 常量宣告
            double r;
            Console.WriteLine("Enter Radius: ");
            r = Convert.ToDouble(Console.ReadLine());
            double areaCircle = pi * r * r;
            Console.WriteLine("Radius: {0}, Area: {1}", r, areaCircle);
            Console.ReadLine();
        }
    }
}

編譯執行結果:

Enter Radius: 
3
Radius: 3, Area: 28.27431

7、方法的定義和呼叫

  • 方法的定義
    語法如下:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
   Method Body
}

下面是方法的各個元素:

  • Access Specifier:訪問修飾符,這個決定了變數或方法對於另一個類的可見性。
  • Return type:返回型別,一個方法可以返回一個值。返回型別是方法返回的值的資料型別。如果方法不返回任何值,則返回型別為 void
  • Method name:方法名稱,是一個唯一的識別符號,且是大小寫敏感的。它不能與類中宣告的其他識別符號相同。
  • Parameter list:引數列表,使用圓括號括起來,該引數是用來傳遞和接收方法的資料。引數列表是指方法的引數型別、順序和數量。引數是可選的,也就是說,一個方法可能不包含引數。
  • Method body:方法主體,包含了完成任務所需的指令集。

例項:
下面的程式碼片段顯示一個函式 FindMax,它接受兩個整數值,並返回兩個中的較大值。它有 public 訪問修飾符,所以它可以使用類的例項從類的外部進行訪問。

class NumberManipulator
{
   public int FindMax(int num1, int num2)
   {
      /* 區域性變數宣告 */
      int result;

      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result;
   }
   ...
}
  • 方法的呼叫
using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public int FindMax(int num1, int num2)
      {
         /* 區域性變數宣告 */
         int result;

         if (num1 > num2)
            result = num1;
         else
            result = num2;

         return result;
      }
      static void Main(string[] args)
      {
         /* 區域性變數定義 */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();

         //呼叫 FindMax 方法
         ret = n.FindMax(a, b);
         Console.WriteLine("最大值是: {0}", ret );
         Console.ReadLine();
      }
   }
}

編譯執行後的結果:

最大值是: 200

您也可以使用類的例項從另一個類中呼叫其他類的公有方法。例如,方法 FindMax 屬於 NumberManipulator 類,您可以從另一個類 Test 中呼叫它。

using System;

namespace CalculatorApplication
{
    class NumberManipulator
    {
        public int FindMax(int num1, int num2)
        {
            /* 區域性變數宣告 */
            int result;

            if (num1 > num2)
                result = num1;
            else
                result = num2;

            return result;
        }
    }
    class Test
    {
        static void Main(string[] args)
        {
            /* 區域性變數定義 */
            int a = 100;
            int b = 200;
            int ret;
            NumberManipulator n = new NumberManipulator();
            //呼叫 FindMax 方法
            ret = n.FindMax(a, b);
            Console.WriteLine("最大值是: {0}", ret );
            Console.ReadLine();

        }
    }
}

編譯執行的結果:

最大值是: 200
  • 遞迴方法的呼叫
    一個方法可以自我呼叫。這就是所謂的 遞迴。下面的例項使用遞迴函式計算一個數的階乘:
using System;

namespace CalculatorApplication
{
    class NumberManipulator
    {
        public int factorial(int num)
        {
            /* 區域性變數定義 */
            int result;

            if (num == 1)
            {
                return 1;
            }
            else
            {
                result = factorial(num - 1) * num;
                return result;
            }
        }

        static void Main(string[] args)
        {
            NumberManipulator n = new NumberManipulator();
            //呼叫 factorial 方法
            Console.WriteLine("6 的階乘是: {0}", n.factorial(6));
            Console.WriteLine("7 的階乘是: {0}", n.factorial(7));
            Console.WriteLine("8 的階乘是: {0}", n.factorial(8));
            Console.ReadLine();

        }
    }
}

編譯執行後的結果:

6 的階乘是: 720
7 的階乘是: 5040
8 的階乘是: 40320
  • 引數傳遞
    當呼叫帶有引數的方法時,您需要向方法傳遞引數。在 C# 中,有三種向方法傳遞引數的方式:
方式描述
值引數這種方式複製引數的實際值給函式的形式引數,實參和形參使用的是兩個不同記憶體中的值。在這種情況下,當形參的值發生改變時,不會影響實參的值,從而保證了實引數據的安全。
引用引數這種方式複製引數的記憶體位置的引用給形式引數。這意味著,當形參的值發生改變時,同時也改變實參的值。
輸出引數這種方式可以返回多個值。
  • 按值引數傳遞

這是引數傳遞的預設方式。在這種方式下,當呼叫一個方法時,會為每個值引數建立一個新的儲存位置。
實際引數的值會複製給形參,實參和形參使用的是兩個不同記憶體中的值。所以,當形參的值發生改變時,不會影響實參的值,從而保證了實引數據的安全。下面的例項演示了這個概念:

using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(int x, int y)
      {
         int temp;

         temp = x; /* 儲存 x 的值 */
         x = y;    /* 把 y 賦值給 x */
         y = temp; /* 把 temp 賦值給 y */
      }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 區域性變數定義 */
         int a = 100;
         int b = 200;

         Console.WriteLine("在交換之前,a 的值: {0}", a);
         Console.WriteLine("在交換之前,b 的值: {0}", b);

         /* 呼叫函式來交換值 */
         n.swap(a, b);

         Console.WriteLine("在交換之後,a 的值: {0}", a);
         Console.WriteLine("在交換之後,b 的值: {0}", b);

         Console.ReadLine();
      }
   }
}

編譯執行後的結果:

在交換之前,a 的值:100
在交換之前,b 的值:200
在交換之後,a 的值:200
在交換之後,b 的值:100

結果表明,swap 函式內的值改變了,且這個改變可以在 Main 函式中反映出來。

  • 按輸出傳遞引數

return 語句可用於只從函式中返回一個值。但是,可以使用 輸出引數 來從函式中返回兩個值。輸出引數會把方法輸出的資料賦給自己,其他方面與引用引數相似。

下面的例項演示了這點:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValue(out int x )
      {
         int temp = 5;
         x = temp;
      }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 區域性變數定義 */
         int a = 100;

         Console.WriteLine("在方法呼叫之前,a 的值: {0}", a);

         /* 呼叫函式來獲取值 */
         n.getValue(out a);

         Console.WriteLine("在方法呼叫之後,a 的值: {0}", a);
         Console.ReadLine();

      }
   }
}

編譯執行後的結果:

在方法呼叫之前,a 的值: 100
在方法呼叫之後,a 的值: 5

提供給輸出引數的變數不需要賦值。當需要從一個引數沒有指定初始值的方法中返回值時,輸出引數特別有用。請看下面的例項,來理解這一點

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValues(out int x, out int y )
      {
          Console.WriteLine("請輸入第一個值: ");
          x = Convert.ToInt32(Console.ReadLine());
          Console.WriteLine("請輸入第二個值: ");
          y = Convert.ToInt32(Console.ReadLine());
      }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 區域性變數定義 */
         int a , b;

         /* 呼叫函式來獲取值 */
         n.getValues(out a, out b);

         Console.WriteLine("在方法呼叫之後,a 的值: {0}", a);
         Console.WriteLine("在方法呼叫之後,b 的值: {0}", b);
         Console.ReadLine();
      }
   }
}

編譯執行後的結果:

請輸入第一個值:
7
請輸入第二個值:
8
在方法呼叫之後,a 的值: 7
在方法呼叫之後,b 的值: 8

8、方法中的引數,返回值

  • 方法中引數的型別有三種
in型引數

int 型引數通過值傳遞的方式將數值傳入方法中,即我們在Java中常見的方法。

ref型引數

該種類型的引數傳遞變數地址給方法(引用傳遞),傳遞前變數必須初始化。

該型別與out型的區別在與:

1).ref 型傳遞變數前,變數必須初始化,否則編譯器會報錯, 而 out 型則不需要初始化
2).ref 型傳遞變數,數值可以傳入方法中,而 out 型無法將資料傳入方法中。換而言之,ref 型有進有出,out 型只出不進。

out 型引數

與 ref 型類似,僅用於傳回結果。

注意:

1). out型資料在方法中必須要賦值,否則編譯器會報錯。

eg:如下圖若將程式碼中的sum1方法的方法體

改為 a+=b; 則編譯器會報錯。原因:out 型只出不進,在沒給 a 賦值前是不能使用的

改為 b+=b+2; 編譯器也會報錯。原因:out 型資料在方法中必須要賦值。

2). 過載方法時若兩個方法的區別僅限於一個引數型別為ref 另一個方法中為out,編譯器會報錯

eg:若將下面的程式碼中將方法名 vsum1 改為 sum(或者將方法名 sum 改為 sum1),編譯器會報錯。

Error 1 Cannot define overloaded method ‘sum’ because it differs from another method only on ref and out

原因:引數型別區別僅限於 為 ref 與為 out 時,若過載對編譯器而言兩者的元資料表示完全相同。

class C
{
    //1. in型引數
    public void sum(int a, int b) {
        a += b;
    }
    //2. ref型引數
    public void sum(ref int a, int b)
    {
        a += b;
    }
    //3. out型引數
    public void sum1(out int a, int b)
    {
        a = b+2;
    }
    public static void Main(string[] args)
    {
        C c = new C();
        int a = 1, b = 2;
        c.sum(a,b);
        Console.WriteLine("a:{0}", a);
        a = 1; b = 2;
        c.sum(ref a, b);
        Console.WriteLine("ref a:{0}", a);
        a = 1; b = 2;
        c.sum1(out a, b);
        Console.WriteLine("out a:{0}", a);
    }
}

輸出結果:
這裡寫圖片描述
從程式碼也可以看出,int 型引數為值傳遞,所以當將變數 a 傳入方法時,變數 a 的值並不會發生變化。而 ref 型引數,由於是引用傳遞,將變數的值和地址都傳入方法中故變數值改變。out 型無法將變數的值傳入。但可以將變數的地址傳入併為該地址上的變數賦值。

  • 按值傳遞引數的問題:

為什麼即使在函式內改變了值,值也沒有發生任何的變化呢?

在交換之前,a 的值:100
在交換之前,b 的值:200
在交換之後,a 的值:100
在交換之後,b 的值:200

解析:

呼叫一個方法時相當於複製一個物件到新分配的記憶體中,方法完畢物件也就del了,兩個變數是不同的兩個地址,a只不過是棧裡的臨時變數而已,和主函式裡的變數沒有關係,因此不會改變b的值。

而指標和引用直接訪問記憶體地址,故直接修改所指向的物件,兩者指向同一變數。

9、類的定義

定義一個類的時候相當於定義了一個數據型別的藍圖,本身沒有定義任何資料,但是它定義了類的名稱意味著什麼,就是說可以在這個類由什麼物件組成,以及在這個物件上可以執行什麼操作

  • 累的定義
    關鍵字 class 後跟類的名稱,類的主體包含在一段花括號中{},下面是類的一般形式
<access specifier> class  class_name 
{
    // member variables
    <access specifier> <data type> variable1;
    <access specifier> <data type> variable2;
    ...
    <access specifier> <data type> variableN;
    // member methods
    <access specifier> <return type> method1(parameter_list) 
    {
        // method body 
    }
    <access specifier> <return type> method2(parameter_list) 
    {
        // method body 
    }
    ...
    <access specifier> <return type> methodN(parameter_list) 
    {
        // method body 
    }
}

請注意:

  • 訪問識別符號 <access specifier> 指定了對類及其成員的訪問規則。如果沒有指定,則使用預設的訪問識別符號。類的預設訪問識別符號是 internal,成員的預設訪問識別符號是 private
  • 資料型別 <data type> 指定了變數的型別,返回型別 <return type> 指定了返回的方法返回的資料型別。
  • 如果要訪問類的成員,你要使用點(.)運算子。
  • 點運算子連結了物件的名稱和成員的名稱。

下面的例項說明了目前為止所討論的概念:

using System;
namespace BoxApplication
{
    class Box
    {
       public double length;   // 長度
       public double breadth;  // 寬度
       public double height;   // 高度
    }
    class Boxtester
    {
        static void Main(string[] args)
        {
            Box Box1 = new Box();        // 宣告 Box1,型別為 Box
            Box Box2 = new Box();        // 宣告 Box2,型別為 Box
            double volume = 0.0;         // 體積

            // Box1 詳述
            Box1.height = 5.0;
            Box1.length = 6.0;
            Box1.breadth = 7.0;

            // Box2 詳述
            Box2.height = 10.0;
            Box2.length = 12.0;
            Box2.breadth = 13.0;

            // Box1 的體積
            volume = Box1.height * Box1.length * Box1.breadth;
            Console.WriteLine("Box1 的體積: {0}",  volume);

            // Box2 的體積
            volume = Box2.height * Box2.length * Box2.breadth;
            Console.WriteLine("Box2 的體積: {0}", volume);
            Console.ReadKey();
        }
    }
}

編譯執行後的結果:

Box1 的體積: 210
Box2 的體積: 1560
  • 成員函式和封裝
    類的成員函式是一個在類定義中有它的定義或原型的函式,就像其他變數一樣。作為類的一個成員,它能在類的任何物件上操作,且能訪問該物件的類的所有成員。

成員變數是物件的屬性(從設計角度),且它們保持私有來實現封裝。這些變數只能使用公共成員函式來訪問。

讓我們使用上面的概念來設定和獲取一個類中不同的類成員的值:

using System;
namespace BoxApplication
{
    class Box
    {
       private double length;   // 長度
       private double breadth;  // 寬度
       private double height;   // 高度
       public void setLength( double len )
       {
            length = len;
       }

       public void setBreadth( double bre )
       {
            breadth = bre;
       }

       public void setHeight( double hei )
       {
            height = hei;
       }
       public double getVolume()
       {
           return length * breadth * height;
       }
    }
    class Boxtester
    {
        static void Main(string[] args)
        {
            Box Box1 = new Box();        // 宣告 Box1,型別為 Box
            Box Box2 = new Box();         // 宣告 Box2,型別為 Box
            double volume;                 // 體積


            // Box1 詳述
            Box1.setLength(6.0);
            Box1.setBreadth(7.0);
            Box1.setHeight(5.0);

            // Box2 詳述
            Box2.setLength(12.0);
            Box2.setBreadth(13.0);
            Box2.setHeight(10.0);

            // Box1 的體積
            volume = Box1.getVolume();
            Console.WriteLine("Box1 的體積: {0}" ,volume);

            // Box2 的體積
            volume = Box2.getVolume();
            Console.WriteLine("Box2 的體積: {0}", volume);

            Console.ReadKey();
        }
    }
}

編譯執行後的結果:

Box1 的體積: 210
Box2 的體積: 1560
  • C# 中的建構函式
    類的 建構函式 是類的一個特殊的成員函式,當建立類的新物件時執行。

建構函式的名稱與類的名稱完全相同,它沒有任何返回型別。

下面的例項說明了建構函式的概念:

using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // 線條的長度
      public Line()
      {
         Console.WriteLine("物件已建立");
      }

      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line();    
         // 設定線條長度
         line.setLength(6.0);
         Console.WriteLine("線條的長度: {0}", line.getLength());
         Console.ReadKey();
      }
   }
}

編譯執行後的結果:

物件已建立
線條的長度: 6

預設的建構函式沒有任何引數。但是如果你需要一個帶有引數的建構函式可以有引數,這種建構函式叫做引數化建構函式。這種技術可以幫助你在建立物件的同時給物件賦初始值,具體請看下面例項:

using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // 線條的長度
      public Line(double len)  // 引數化建構函式
      {
         Console.WriteLine("物件已建立,length = {0}", len);
         length = len;
      }

      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line(10.0);
         Console.WriteLine("線條的長度: {0}", line.getLength()); 
         // 設定線條長度
         line.setLength(6.0);
         Console.WriteLine("線條的長度: {0}", line.getLength()); 
         Console.ReadKey();
      }
   }
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

物件已建立,length = 10
線條的長度: 10
線條的長度: 6
  • C# 中的解構函式
    類的 解構函式 是類的一個特殊的成員函式,當類的物件超出範圍時執行。

解構函式的名稱是在類的名稱前加上一個波浪形(~)作為字首,它不返回值,也不帶任何引數。

解構函式用於在結束程式(比如關閉檔案、釋放記憶體等)之前釋放資源。解構函式不能繼承或過載。

下面的例項說明了解構函式的概念:

using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // 線條的長度
      public Line()  // 建構函式
      {
         Console.WriteLine("物件已建立");
      }
      ~Line() //解構函式
      {
         Console.WriteLine("物件已刪除");
      }

      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line();
         // 設定線條長度
         line.setLength(6.0);
         Console.WriteLine("線條的長度: {0}", line.getLength());           
      }
   }
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

物件已建立
線條的長度: 6
物件已刪除

  • C# 類的靜態成員
    我們可以使用 static 關鍵字把類成員定義為靜態的。當我們宣告一個類成員為靜態時,意味著無論有多少個類的物件被建立,只會有一個該靜態成員的副本。

關鍵字 static 意味著類中只有一個該成員的例項。靜態變數用於定義常量,因為它們的值可以通過直接呼叫類而不需要建立類的例項來獲取。靜態變數可在成員函式或類的定義外部進行初始化。你也可以在類的定義內部初始化靜態變數。

下面的例項演示了靜態變數的用法:

using System;
namespace StaticVarApplication
{
    class StaticVar
    {
       public static int num;
        public void count()
        {
            num++;
        }
        public int getNum()
        {
            return num;
        }
    }
    class StaticTester
    {
        static void Main(string[] args)
        {
            StaticVar s1 = new StaticVar();
            StaticVar s2 = new StaticVar();
            s1.count();
            s1.count();
            s1.count();
            s2.count();
            s2.count();
            s2.count();         
            Console.WriteLine("s1 的變數 num: {0}", s1.getNum());
            Console.WriteLine("s2 的變數 num: {0}", s2.getNum());
            Console.ReadKey();
        }
    }
}

編譯執行後的結果:

s1 的變數 num: 6
s2 的變數 num: 6

你也可以把一個成員函式宣告為 static。這樣的函式只能訪問靜態變數。靜態函式在物件被建立之前就已經存在。下面的例項演示了靜態函式的用法:

using System;
namespace StaticVarApplication
{
    class StaticVar
    {
       public static int num;
        public void count()
        {
            num++;
        }
        public static int getNum()
        {
            return num;
        }
    }
    class StaticTester
    {
        static void Main(string[] args)
        {
            StaticVar s = new StaticVar();
            s.count();
            s.count();
            s.count();                   
            Console.WriteLine("變數 num: {0}", StaticVar.getNum());
            Console.ReadKey();
        }
    }
}

編譯執行後的結果:

變數 num: 3

10、列舉型別:

列舉是一組命名整型常量。列舉型別是使用 enum 關鍵字宣告的。

C# 列舉是值型別。換句話說,列舉包含自己的值,且不能繼承或傳遞繼承。
- 宣告
語法

enum <enum_name>
{ 
    enumeration list 
};
enum RoleType{     //關鍵字+命名
     apple,          //物件,以逗號分隔
     pen,
     erase
}
RoleType rt = RoleType.apple;   //使用列舉

其中,

  • enum_name 指定列舉的型別名稱。
  • enumeration list 是一個用逗號分隔的識別符號列表。

列舉列表中的每個符號代表一個整數值,一個比它前面的符號大的整數值。預設情況下,第一個列舉符號的值是 0.例如:

enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };

例項:
下面的例項演示了列舉變數的用法:

using System;
namespace EnumApplication
{
   class EnumProgram
   {
      enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };

      static void Main(string[] args)
      {
         int WeekdayStart = (int)Days.Mon;
         int WeekdayEnd = (int)Days.Fri;
         Console.WriteLine("Monday: {0}", WeekdayStart);
         Console.WriteLine("Friday: {0}", WeekdayEnd);
         Console.ReadKey();
      }
   }
}

編譯執行後的結果:

Monday: 1
Friday: 5

11、元件的建立與使用

這裡寫圖片描述