C# 8.0 Introduce Operators ใหม่สำหรับ Indexers:
- ^ Operator (Index from End) - คืนค่า Index ที่ Relative กับ End ของ Sequence/Collection
- .. Operator (Range) - ระบุ Range ของ Elements
^ Operator - Index from End
วิธีที่ Concise และง่ายที่สุดในการหา Elements ตัวท้ายเทียบกับวิธีเก่า
// เก่า
var last = list[list.Count - 1];
var secondLast = list[list.Count - 2];
// ใหม่ (C# 8.0)
var last = list[^1]; // ตัวสุดท้าย
var secondLast = list[^2]; // ตัวก่อนสุดท้าย
var thirdLast = list[^3]; // ตัวที่ 3 จากท้าย
.. Operator - Range
ระบุช่วง [start..end) - Include start, Exclude end
var array = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var firstThree = array[0..3]; // [0, 1, 2]
var lastThree = array[^3..]; // [7, 8, 9] (^3 = index 7, .. = ถึงสุด)
var middle = array[2..7]; // [2, 3, 4, 5, 6]
var all = array[..]; // ทั้ง Array (Copy)
var from2 = array[2..]; // Index 2 ถึงสุด
var to5 = array[..5]; // เริ่มต้น ถึง Index 4
ตัวอย่างครบถ้วน
public class Employee {
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
}
public class Company {
public List Employees { get; }
public Company() {
Employees = new List {
new Employee { EmployeeId = 1, Name = "AA", Gender = "Male" },
new Employee { EmployeeId = 2, Name = "BB", Gender = "Female" },
new Employee { EmployeeId = 3, Name = "CC", Gender = "Male" },
new Employee { EmployeeId = 4, Name = "DD", Gender = "Female" },
new Employee { EmployeeId = 5, Name = "EE", Gender = "Female" },
new Employee { EmployeeId = 6, Name = "FF", Gender = "Male" },
new Employee { EmployeeId = 7, Name = "GG", Gender = "Male" },
new Employee { EmployeeId = 8, Name = "HH", Gender = "Male" },
};
}
// Custom Indexer
public string this[int employeeId] {
get => Employees.FirstOrDefault(e => e.EmployeeId == employeeId)?.Name;
set {
var emp = Employees.FirstOrDefault(e => e.EmployeeId == employeeId);
if (emp != null) emp.Name = value;
}
}
}
class Program {
static void Main() {
Company company = new Company();
// แสดงชื่อพนักงาน
Console.WriteLine($"Id=2: {company[2]}");
Console.WriteLine($"Id=5: {company[5]}");
Console.WriteLine($"Id=8: {company[8]}");
// เปลี่ยนชื่อผ่าน Indexer
company[2] = "Employee 2 Changed";
company[5] = "Employee 5 Changed";
company[8] = "Employee 8 Changed";
Console.WriteLine();
Console.WriteLine($"Id=2: {company[2]}");
Console.WriteLine($"Id=5: {company[5]}");
Console.WriteLine($"Id=8: {company[8]}");
// ใช้ ^ Operator กับ List โดยตรง
company.Employees[^2].Name = "Employee 2 from End";
company.Employees[^5].Name = "Employee 5 from End";
company.Employees[^8].Name = "Employee 8 from End";
Console.WriteLine();
Console.WriteLine($"^2: {company.Employees[^2].Name}");
Console.WriteLine($"^5: {company.Employees[^5].Name}");
Console.WriteLine($"^8: {company.Employees[^8].Name}");
// Range Operator
var top3 = company.Employees[..3];
var bottom3 = company.Employees[^3..];
Console.WriteLine("\nTop 3:");
foreach (var e in top3) Console.WriteLine(e.Name);
Console.WriteLine("\nBottom 3:");
foreach (var e in bottom3) Console.WriteLine(e.Name);
Console.ReadLine();
}
}
Output
Id=2: BB
Id=5: EE
Id=8: HH
Id=2: Employee 2 Changed
Id=5: Employee 5 Changed
Id=8: Employee 8 Changed
^2: Employee 2 from End
^5: Employee 5 from End
^8: Employee 8 from End
Top 3:
AA
BB
CC
Bottom 3:
FF
GG
HH
Index และ Range Structs
// Index Struct
Index i1 = 3; // From start (implicit conversion)
Index i2 = ^3; // From end
Index i3 = Index.FromStart(3);
Index i4 = Index.FromEnd(3);
// Range Struct
Range r1 = 1..5; // Start=1, End=5
Range r2 = ..5; // Start=0, End=5
Range r3 = 2..; // Start=2, End=^0
Range r4 = ^3..^1; // Start=^3, End=^1
// ใช้กับ Array/List
var slice = array[r1]; // array[1..5]
การใช้งานกับ String
string text = "Hello World";
var word1 = text[..5]; // "Hello"
var word2 = text[6..]; // "World"
var lastChar = text[^1]; // "d"
var lastWord = text[^5..]; // "World"
ข้อควรระวัง
^0= Index หลัง Element สุดท้าย (เท่ากับ Length) - ใช้ได้ใน Range เท่านั้น- Index Out of Range จะโยน
IndexOutOfRangeException - ทำงานกับ Types ที่มี Indexer และ Property
LengthหรือCount(Arrays, List, String, Span, Memory) - Range Return Type เหมือนกับ Source (Array → Array, List → List, String → String)