首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 型別轉換完全指南:數值、字串、日期、物件、集合、編碼

     編輯:關於C語言

轉換分類總覽

類別方向關鍵字/方法失敗行為效能
隱含轉換數值擴大int → long, float → double編譯時保證安全零成本
參考向上Derived → Base, T → Interface永不失敗零成本
顯式轉型數值縮小(int)longVal, (byte)intVal溢位截斷 / checked 擲出極低
參考向下(Derived)baseRefInvalidCastException極低
介面轉換(IMyInterface)objInvalidCastException極低
Parse/TryParse字串→數值/日期/Enum/Guidint.Parse, DateTime.TryParseFormatException / 回傳 false中 (解析開銷)
字串→其他Enum.TryParse, Guid.TryParse回傳 false中
ToString/格式化數值/日期/物件→字串ToString("F2"), $"{val:N}"不失敗 (虛擬方法)低~中
Convert 類別任意基礎型別互轉Convert.ToInt32, ToDateTimeOverflowException / FormatException中 (含 null 檢查)
編碼轉換字串↔位元組陣列Encoding.UTF8.GetBytes/GetStringEncoderFallbackException中
集合轉換List/Array/IEnumerable 互轉.ToList(), .ToArray(), .ToDictionary()不失敗 (配置新集合)O(N)

數值型別轉換詳解

隱含轉換 (安全、無資料遺失)


// 整數擴大
int i = 42;
long l = i;           // 隱含
float f = i;          // 隱含 (精度可能遺失,但 C# 允許)
double d = f;         // 隱含

// 參考向上
string s = "hello";
object o = s;         // 隱含
IEnumerable en = new List(); // 隱含

顯式轉型 (可能遺失資料/擲出例外)


long big = 300;
int small = (int)big;      // 300 (正常)
long huge = 3_000_000_000;
int overflow = (int)huge;  // -1294967296 (截斷,無例外!)

// 啟用溢位檢查
checked
{
    int safe = (int)huge;  // ❌ OverflowException
}

// 更安全:Convert.ToInt32 (內含溢位檢查)
int safe2 = Convert.ToInt32(huge); // ❌ OverflowException

浮點數轉整數 (截斷向零)


double d = 3.9;
int trunc = (int)d;        // 3 (直接捨棄小數)
int round = (int)Math.Round(d); // 4 (四捨五入)
int floor = (int)Math.Floor(d); // 3
int ceil = (int)Math.Ceiling(d); // 4

字串與數值/日期互轉

Parse / TryParse (標準、高效能)


// 整數
bool ok = int.TryParse("123", out int val);     // true, val=123
bool ok2 = int.TryParse("abc", out int val2);   // false, val2=0

// 進制指定
int hex = int.Parse("FF", System.Globalization.NumberStyles.HexNumber); // 255

// 浮點數 (文化特性敏感)
double d = double.Parse("3.14", CultureInfo.InvariantCulture); // 強制用 . 做小數點

// 日期時間
DateTime dt = DateTime.Parse("2024-03-15 14:30"); // 依目前文化特性
DateTime dt2 = DateTime.ParseExact("15/03/2024", "dd/MM/yyyy", CultureInfo.InvariantCulture);

// Enum
DayOfWeek dow = Enum.Parse("Monday"); // C# 7.3+ 泛型 Parse
bool ok3 = Enum.TryParse("Friday", out DayOfWeek dow2);

// Guid
Guid g = Guid.Parse("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");

Convert 類別 (支援 null、物件輸入)


object[] inputs = { "123", 456L, 3.14, true, null, DateTime.Now };

foreach (var input in inputs)
{
    int i = Convert.ToInt32(input); // null → 0, true → 1, DateTime → Exception
    // Convert 內部處理 null、IConvertible、IFormattable
}

ToString 格式化 (數值/日期/Enum)


int n = 12345;
n.ToString("N");      // "12,345.00" (千分位)
n.ToString("C");      // "NT$12,345.00" (貨幣)
n.ToString("X");      // "3039" (十六進位大寫)
n.ToString("D8");     // "00012345" (補零)

double d = 0.1234;
d.ToString("P");      // "12.34%" (百分比)
d.ToString("E");      // "1.234000E-001" (科學記號)

DateTime now = DateTime.Now;
now.ToString("yyyy-MM-dd HH:mm:ss"); // "2024-03-15 14:30:05"
now.ToString("o");                    // "2024-03-15T14:30:05.1234567+08:00" (ISO 8601)

DayOfWeek dow = DayOfWeek.Monday;
dow.ToString();        // "Monday"
dow.ToString("d");     // "1" (底層數值)

物件型別轉換模式

is / as 模式匹配 (C# 7+)


object obj = "hello";

// 傳統
if (obj is string s)
    Console.WriteLine(s.Length);

// C# 7 switch 運算式
string result = obj switch
{
    int i => $"Integer: {i}",
    string s => $"String: {s.Length} chars",
    DateTime dt => dt.ToString("o"),
    null => "Null",
    _ => "Unknown"
};

// as 操作符 (僅參考型別,失敗回傳 null)
string str = obj as string; // null if not string

使用者定義轉換運算子


struct Celsius
{
    public double Degrees { get; }
    public Celsius(double d) => Degrees = d;

    // 隱式:double → Celsius (安全)
    public static implicit operator Celsius(double d) => new Celsius(d);
    
    // 顯式:Celsius → double (可能遺失單位語意)
    public static explicit operator double(Celsius c) => c.Degrees;
    
    // 互轉
    public static implicit operator Fahrenheit(Celsius c) => new Fahrenheit(c.Degrees * 9/5 + 32);
}

struct Fahrenheit
{
    public double Degrees { get; }
    public Fahrenheit(double d) => Degrees = d;
    public static implicit operator Fahrenheit(double d) => new Fahrenheit(d);
}

var c = new Celsius(25);
Fahrenheit f = c;           // 隱式轉換
double d = (double)c;       // 顯式轉型

編碼與位元組陣列轉換


string text = "中文 English 😀";

// 字串 → 位元組 (指定編碼)
byte[] utf8 = Encoding.UTF8.GetBytes(text);        // 最通用
byte[] utf16 = Encoding.Unicode.GetBytes(text);    // UTF-16 LE (Windows 內部)
byte[] ascii = Encoding.ASCII.GetBytes(text);      // 非 ASCII 字元變 '?'

// 位元組 → 字串
string back = Encoding.UTF8.GetString(utf8);

// Base64 (二進位轉文字傳輸)
string b64 = Convert.ToBase64String(utf8);
byte[] decoded = Convert.FromBase64String(b64);

// 取得編碼物件
Encoding utf8Enc = Encoding.UTF8;
Encoding gb2312 = Encoding.GetEncoding("gb2312"); // 繁體/簡體中文舊系統
Encoding big5 = Encoding.GetEncoding("big5");

集合與陣列轉換 (LINQ)


int[] array = { 1, 2, 3 };
List list = new List { 4, 5 };

// 陣列 ↔ List
List fromArray = array.ToList();
int[] fromList = list.ToArray();

// IEnumerable 具體化
IEnumerable query = array.Where(x => x > 1);
List materialized = query.ToList(); // 立即執行

// Dictionary
var dict = list.ToDictionary(x => x, x => x * 2); // {1:2, 2:4, 3:6, 4:8, 5:10}
var lookup = list.ToLookup(x => x % 2);           // 分組查找

// HashSet (去重)
HashSet unique = list.ToHashSet();

// Stack/Queue
Stack stack = new Stack(list);
Queue queue = new Queue(list);

// DataTable → List (常見 ADO.NET 場景)
List dtos = dataTable.AsEnumerable()
    .Select(row => new MyDto { Id = row.Field("Id"), Name = row.Field("Name") })
    .ToList();

常見陷阱與最佳實踐

陷阱錯誤做法正確做法
浮點數比較if (d == 0.1)if (Math.Abs(d - 0.1) < 1e-9)
整數溢位靜默int x = 2_000_000_000 + 2_000_000_000;用 checked 區塊或 long
字串解析例外int.Parse(userInput)int.TryParse(userInput, out _)
日期文化特性DateTime.Parse("03/04/2024") (月/日 vs 日/月)ParseExact(..., "yyyy-MM-dd", InvariantCulture)
編碼預設值Encoding.Default (系統相依)明確指定 Encoding.UTF8
ToString NullReferenceobj.ToString() (obj 可能 null)obj?.ToString() ?? "" 或 Convert.ToString(obj)
as 後未檢查 null(obj as IDisposable).Dispose()(obj as IDisposable)?.Dispose()

效能建議

  • 熱路徑避免装箱:int → object 裝箱配置記憶體,用泛型/介面避免
  • 大量字串轉數值:Span + Utf8Parser (System.Buffers.Text) 比 Parse 快 2-5 倍
  • 重複格式化:緩衝 StringBuilder、避免頻繁 ToString 配置
  • 編碼重用:Encoding.UTF8 是單例,勿重複 new UTF8Encoding()

結語

型別轉換是 C# 程式無處不在的基石操作。掌握「隱含 vs 顯式」、「Parse vs TryParse vs Convert」、「編碼明確指定」、「集合具體化時機」、「模式匹配現代語法」,能寫出型別安全、效能優異、錯誤可控的程式碼。記住:編譯器能檢查的靜態轉換優於執行時動態轉換,失敗快速顯性優於靜默錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved