ภาพรวม
ใช้ Substring(0, 1) หรือ Indexer [0] หรือ LINQ First() เพื่อดึงตัวอักษรแรก
โค้ดตัวอย่าง
using System;
public class Demo {
public static void Main() {
string str = "Welcome to the Planet!";
// วิธีที่ 1: Substring (คืนค่า string)
string firstChar1 = str.Substring(0, 1);
Console.WriteLine($"Substring: '{firstChar1}'");
// วิธีที่ 2: Indexer (คืนค่า char)
char firstChar2 = str[0];
Console.WriteLine($"Indexer: '{firstChar2}'");
// วิธีที่ 3: LINQ First()
char firstChar3 = str.First();
Console.WriteLine($"LINQ First(): '{firstChar3}'");
// วิธีที่ 4: Take(1) - คืนค่า IEnumerable<char>
string firstChar4 = new string(str.Take(1).ToArray());
Console.WriteLine($"Take(1): '{firstChar4}'");
}
}
ผลลัพธ์
Substring: 'W'
Indexer: 'W'
LINQ First(): 'W'
Take(1): 'W'
เปรียบเทียบ
| วิธี | Return Type | Performance | Empty String Safety |
|---|---|---|---|
str[0] | char | เร็วที่สุด O(1) | Throw IndexOutOfRangeException |
str.Substring(0,1) | string | O(1) แต่ allocate string ใหม่ | Throw ArgumentOutOfRangeException |
str.First() | char | ช้ากว่า (iterator overhead) | Throw InvalidOperationException |
str.FirstOrDefault() | char | ช้ากว่า | Safe: คืนค่า '\0' (null char) |
Best Practice: Safe Access
// ตรวจสอบก่อนใช้
if (!string.IsNullOrEmpty(str)) {
char first = str[0];
}
// หรือใช้ pattern matching (C# 8+)
char first = str switch {
{ Length: > 0 } s => s[0],
_ => '\0'
};
// Extension method สำหรับความปลอดภัย
public static class StringExtensions {
public static char? FirstOrNull(this string s) =>
string.IsNullOrEmpty(s) ? null : s[0];
}
กรณีพิเศษ: Unicode / Grapheme Clusters
string s = "👨👩👧👦"; // Family emoji = 1 grapheme, หลาย char
Console.WriteLine($"Length: {s.Length}"); // 11 (UTF-16 code units)
Console.WriteLine($"First char: '{s[0]}'"); // '👨' (แค่ส่วนแรก)
// ต้องใช้ StringInfo สำหรับ grapheme clusters
using System.Globalization;
var si = new StringInfo(s);
Console.WriteLine($"Text elements: {si.LengthInTextElements}"); // 1