C# 入門指南
單元 9 - 列舉與結構
列舉 (enumeration) 與結構 (structure) 都是實值型態 (value type) ,列舉用關鍵字 (keyword) enum 宣告,結構則是用關鍵字 struct 定義
列舉是一組用識別字定義的整數常數,宣告定義如下
enum Day {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
這樣 Day 就會是列舉,裡頭的 Sun 等同於整數 0 ,之後逐次遞增 1 , Mon 等同於整數 1 , Tue 等同於整數 2 ,餘下可類推。
至於實際使用列舉,需要進行型態轉換,例如
using System;
namespace EnumDemo01
{
class Program
{
enum Day {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
static void Main(string[] args)
{
int a = (int) Day.Sun;
int b = (int) Day.Thu;
Console.WriteLine("Sunday: {0}", a);
Console.WriteLine("Thursday: {0}", b);
}
}
}
//《程式語言教學誌》的範例程式
// http://kaiching.org/
// 專案:EnumDemo01
// 檔名:Program.cs
// 功能:示範 C# 的列舉
// 作者:張凱慶
這裡從列舉 Day 中取出 Sun 與 Thu ,然後把這兩個印出來,注意取出必須加上小括弧及型態名稱,進行強制型態轉換
int a = (int) Day.Sun;
int b = (int) Day.Thu;
Console.WriteLine("Sunday: {0}", a);
Console.WriteLine("Thursday: {0}", b);
強制型態轉換是一種型態轉換的手法,用以解決型態不相容的問題。
此例執行結果如下
C:\EnumDemo01> dotnet run |
Sunday: 0 |
Thursday: 4 |
C:\EnumDemo01> |
列舉中的常數可以是任何的整數型態,預設是 int ,其他都要宣告,例如
enum Range: long {Max=2000000000L, Min=1000000000L};
以上將列舉裡面的常數宣告為 long ,同時直接用指派運算子設定整數值,注意整數字面常數 (literal) 最後面的 L 表示這是 long 型態。
以下程式取出 Range 的兩個常數,然後印出來
using System;
namespace EnumDemo02
{
class Program
{
enum Range: long {Max=2000000000L, Min=1000000000L};
static void Main(string[] args)
{
long a = (long) Range.Max;
long b = (long) Range.Min;
Console.WriteLine("Max: {0}", a);
Console.WriteLine("Min: {0}", b);
}
}
}
//《程式語言教學誌》的範例程式
// http://kaiching.org/
// 專案:EnumDemo02
// 檔名:Program.cs
// 功能:示範 C# 的列舉
// 作者:張凱慶
執行結果如下
C:\EnumDemo02> dotnet run |
Max: 2000000000 |
Min: 1000000000 |
C:\EnumDemo02> |
列舉通常會用在需要常數識別字的地方,結構則是簡單的類別 (class) ,例如
using System;
namespace StructDemo01
{
public struct Point1
{
public int x, y;
}
public struct Point2
{
public int x, y;
public Point2(int p1, int p2)
{
x = p1;
y = p2;
}
public void PrintCoordinate()
{
Console.WriteLine("({0}, {1})", x, y);
}
}
class Program
{
static void Main(string[] args)
{
Point1 p1;
p1.x = 10;
p1.y = 2;
Console.WriteLine("p1: ({0}, {1})", p1.x, p1.y);
Point2 p2 = new Point2(11, 22);
p2.PrintCoordinate();
Console.WriteLine("p2: ({0}, {1})", p2.x, p2.y);
}
}
}
//《程式語言教學誌》的範例程式
// http://kaiching.org/
// 專案:StructDemo01
// 檔名:Program.cs
// 功能:示範 C# 的結構
// 作者:張凱慶
這裡定義了兩個結構,首先是 Point1
public struct Point1
{
public int x, y;
}
定義結構使用關鍵字 struct ,裡頭簡單宣告兩個欄位 (field) x 及 y ,注意 public 是宣告存取權限, public 是最寬鬆的存取層級,這讓底下 Program 類別可以使用 Point1 。執行部分在 Program 的 Main() 中,先看到 Point1 的部分
Point1 p1;
p1.x = 10;
p1.y = 2;
Console.WriteLine("p1: ({0}, {1})", p1.x, p1.y);
這裡宣告了 Point1 的變數 p1 ,然後直接用指派運算子設定 x 及 y 兩個欄位,然後印出欄位值。
第二個結構 Point2 除了兩個 x 、 y 欄位之外,另外定義建構子 (constructor) 與 PrintCoordinate() 方法 (method)
public struct Point2
{
public int x, y;
public Point2(int p1, int p2)
{
x = p1;
y = p2;
}
public void PrintCoordinate()
{
Console.WriteLine("({0}, {1})", x, y);
}
}
建構子就是建立結構時所執行的特殊方法,注意建構子跟結構名稱同名,小括弧為參數列 (parameter list) ,然後不需要回傳值 (return value)
public Point2(int p1, int p2)
{
x = p1;
y = p2;
}
「建構子」在 C# 官方文件由機器翻譯成「建構函式」,「建構函式」是沿用 C++ 的翻譯詞彙,問題是 C# 直接定義類別,並無函式(或稱函數,原文皆為 function )的定義,因此本書採用物件導向程式設計常用的翻譯詞「建構子」。
因為建構子是直接建立物件實體的特殊方法,因此建構子不需要回傳值。
PrintCoordinate() 沒有回傳值,宣告為 void ,參數列留空
public void PrintCoordinate()
{
Console.WriteLine("({0}, {1})", x, y);
}
參數列就是實際呼叫建構子或方法提供的參數 (parameter) ,如此例的建構子用參數設定欄位值
Point2 p2 = new Point2(11, 22);
p2.PrintCoordinate();
Console.WriteLine("p2: ({0}, {1})", p2.x, p2.y);
執行結果如下
C:\StructDemo01> dotnet run |
p1: (10, 2) |
(11, 22) |
p2: (11, 22) |
C:\StructDemo01> |
結構只是簡單的類別,並不具有類別的完整功能,下一單元開始討論如何設計類別。
相關教學影片
中英文術語對照 | |
---|---|
類別 | class |
建構子 | constructor |
列舉 | enumeration |
欄位 | field |
關鍵字 | keyword |
字面常數 | literal |
方法 | method |
參數 | parameter |
參數列 | parameter list |
回傳值 | return value |
結構 | structure |
實值型態 | value type |
參考資料 | |
---|---|
1. C# 語言教學課程 | Microsoft Docs - 列舉 | |
2. C# 語言教學課程 | Microsoft Docs - 結構 | |
3. C# 參考 | Microsoft Docs - enum | |
4. C# 參考 | Microsoft Docs - struct | |
5. C# 程式設計手冊 | Microsoft Docs - 使用結構 |
重點整理 |
---|
1. 列舉是一組用識別字定義的整數常數,實際使用需要做強制型態轉換。 |
2. 結構則是簡單的類別,同樣可以定義欄位及方法。 |
問題與討論 |
---|
1. 想一想,列舉的好處在哪裡?可以用在什麼地方? |
2. 結構跟類別有不同? |
練習 |
---|
1. 建立一個新專案 Exercise0901 ,利用列舉及 DateTime 物件的 DayOfWeek 屬性判斷今天是星期幾? |
2. 建立一個新專案 Exercise0902 ,寫一個結構記錄商品名稱、售價、成本,然後印在命令列上。 |