掌握 C# 基礎類型系統是寫出高效、無 Bug 程式的前提。本文系統整理陣列宣告/初始化/多維/不規則、類型轉換 (ToString/Parse/Convert/格式化)、常數/readonly、結構 vs 類別、列舉五大核心主題,附最佳實踐與常見陷阱。
// 1. 分步
string[] names;
names = new string[5];
// 2. 合併
string[] names = new string[5];
// 3. 集合初始化器 (推薦,長度自動推斷)
string[] names = { "Alice", "Bob", "Charlie" };
string[] names = new[] { "Alice", "Bob" }; // 明確型別
string[] names = new string[3] { "A", "B", "C" }; // 固定長度+初始化
0 起,Length 屬性取得長度IndexOutOfRangeException,無邊界檢查優化 (Release 模式仍檢查)
string[,] matrix = new string[3, 2]; // 3列2行,共6元素
matrix[0, 0] = "A1";
matrix[2, 1] = "C2";
// 存取:matrix.GetLength(0) → 3, GetLength(1) → 2
// 記憶體連續佈局,適合矩陣運算
string[][] jagged = new string[2][];
jagged[0] = new string[8]; // 第0行8欄
jagged[1] = new string[2]; // 第1行2欄
// 逐行初始化
int[][] triangle = new int[5][];
for (int i = 0; i < 5; i++)
triangle[i] = new int[i + 1]; // 三角形陣列
| 類型 | 記憶體佈局 | 存取語法 | 適用場景 |
|---|---|---|---|
| 多維 [] | 單一連續區塊 | [i, j] | 矩陣、圖像像素、固定表格 |
| 不規則 [][] | 陣列的陣列,各行獨立分配 | [i][j] | 不規則資料、稀疏矩陣、可變長度列 |
建議:>3 維改用物件/集合/資料表,避免維度爆炸。
int age = 21;
string s = age.ToString(); // "21"
DateTime dt = DateTime.Now;
dt.ToString("D"); // "2024年12月19日 星期四" (長日期)
dt.ToString("G"); // "2024/12/19 上午 10:30:15" (常用)
dt.ToString("T"); // "上午 10:30:15" (長時間)
dt.ToString("t"); // "10:30" (短時間)
dt.ToString("d"); // "2024/12/19" (短日期)
dt.ToString("yyyy-MM-dd HH:mm:ss"); // 自訂格式 "2024-12-19 10:30:15"
int i = int.Parse("123"); // 失敗拋 FormatException
bool ok = int.TryParse("abc", out i); // 失敗回傳 false, i=0, 不拋例外 (推薦)
// 日期解析
DateTime dt = DateTime.Parse("2024-12-19");
DateTime dt = DateTime.ParseExact("19/12/2024", "dd/MM/yyyy", CultureInfo.InvariantCulture);
Convert.ToInt32("123"); // 等同 int.Parse
Convert.ToInt32(12.9); // 13 (銀行家捨入)
Convert.ToBoolean(1); // true
Convert.ToString(123); // "123" (處理 null 回傳 String.Empty)
Convert.ChangeType(val, typeof(int)); // 動態型別轉換
int i = 10;
long l = i; // 隱式擴大轉換
int j = (int)l; // 顯式縮小轉換 (可能溢位)
object obj = "hello";
string s = obj as string; // 失敗回傳 null,不拋例外
bool isStr = obj is string; // 型別檢查 (C# 7+ 模式匹配: obj is string str)
| 特性 | const | readonly |
|---|---|---|
| 初始化 | 宣告時必須賦值 (編譯期常數) | 宣告時或建構函式中 (執行期常數) |
| 型別限制 | 僅基本型別、string、null、enum | 任意型別 |
| 靜態性 | 隱含 static,不可加 static | 實例或 static 皆可 |
| IL 表現 | 值直接內嵌呼叫端 (版本相依風險) | 欄位存取,跨組件安全 |
| 典型用途 | 數學常數、固定設定 | 執行期決定的設定、注入依賴 |
public const double PI = 3.1415926535;
public readonly DateTime StartTime = DateTime.Now; // 每個實例不同
public static readonly Color ThemeColor = Color.FromArgb(0x007ACC); // 單一靜態
| 特性 | struct (值類型) | class (參考類型) |
|---|---|---|
| 儲存位置 | 堆疊 / 內嵌父物件 | 堆積 |
| 指派/傳遞 | 複製值 | 複製參考 |
| 繼承 | 不可繼承 (隱含 sealed),可實作介面 | 單一繼承 |
| 預設值 | 所有欄位歸零 (不可為 null) | null |
| 解構函式 | 無 | 有 (Finalizer) |
| 效能 | 小型、短命、高頻 → 避免 GC | 大型、長命、共享狀態 |
public readonly struct Point3D : IEquatable<Point3D>
{
public double X { get; }
public double Y { get; }
public double Z { get; }
public Point3D(double x, double y, double z) => (X, Y, Z) = (x, y, z);
public double DistanceTo(Point3D other)
=> Math.Sqrt((X-other.X)*(X-other.X) + (Y-other.Y)*(Y-other.Y) + (Z-other.Z)*(Z-other.Z));
public override bool Equals(object obj) => obj is Point3D p && Equals(p);
public bool Equals(Point3D other) => X==other.X && Y==other.Y && Z==other.Z;
public override int GetHashCode() => HashCode.Combine(X, Y, Z);
public static bool operator ==(Point3D a, Point3D b) => a.Equals(b);
public static bool operator !=(Point3D a, Point3D b) => !a.Equals(b);
}
readonly struct (C# 7.2+) 確保不可變,避免防禦性複製IEquatable<T> 避免裝箱GetHashCode/Equals 並提供 ==/!= 運算子
enum Gender : byte { Male = 0, Female = 1 } // 明確底層型別 byte (預設 int)
enum FileAccess { Read = 1, Write = 2, ReadWrite = 3 } // 位旗標建議用 FlagsAttribute
[Flags]
enum Permissions
{
None = 0,
Read = 1 << 0, // 1
Write = 1 << 1, // 2
Execute = 1 << 2, // 4
All = Read | Write | Execute // 7
}
var p = Permissions.Read | Permissions.Write; // 3
bool canRead = p.HasFlag(Permissions.Read); // true (C# 4+)
Gender g = Gender.Male;
string name = g.ToString(); // "Male"
Gender parsed = Enum.Parse<Gender>("Female"); // Female
bool defined = Enum.IsDefined(typeof(Gender), 2); // false
Array values = Enum.GetValues(typeof(Gender)); // 所有值
string[] names = Enum.GetNames(typeof(Gender)); // 所有名稱
// C# 7+ 模式匹配
string desc = g switch
{
Gender.Male => "男性",
Gender.Female => "女性",
_ => "未知"
};
<script runat="server">
void Page_Load()
{
string[] inputs = { text1.Text, text2.Text, text3.Text };
Message1.Text = inputs[0];
Message2.Text = inputs[1];
Message3.Text = inputs[2];
}
</script>
<asp:TextBox ID="text1" runat="server" /><br/>
<asp:TextBox ID="text2" runat="server" TextMode="MultiLine" Rows="5" /><br/>
<asp:TextBox ID="text3" runat="server" TextMode="Password" /><br/>
<asp:Button Text="送出" runat="server" />
<asp:Label ID="Message1" runat="server" /><br/>
<asp:Label ID="Message2" runat="server" /><br/>
<asp:Label ID="Message3" runat="server" />
結語:陣列選對類型 (多維 vs 不規則)、轉換用 TryParse 避免例外、常數分 const/readonly 場景、結構用於小型不可變值型別、列舉善用 Flags 與 HasFlag。這五大基石扎實,C# 進階之路才能走得穩、走得遠。