Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Cách dùng Indexers trong C# 8.0

^ Operator - Toán tử index from the end (chỉ số từ cuối).

Trả về index relative đến cuối của sequence hoặc collection.

Là cách compact và dễ nhất để tìm end elements so với các phương pháp trước.

company.listEmployees[^2].Name = "Employee 2 Name Changed using new Syntax";
company.listEmployees[^5].Name = "Employee 5 Name Changed using new Syntax";
company.listEmployees[^8].Name = "Employee 8 Name Changed using new Syntax";

Ví dụ

public class Employee { 
    public int EmployeeId { get; set; } 
    public string Name { get; set; } 
    public string Gender { get; set; } 
} 

public class Company { 
    public List<Employee> listEmployees; 
    
    public Company() { 
        listEmployees = new List<Employee>(); 
        listEmployees.Add(new Employee { EmployeeId = 1, Name = "SS", Gender = "Male" }); 
        listEmployees.Add(new Employee { EmployeeId = 2, Name = "SSS", Gender = "Female" }); 
        listEmployees.Add(new Employee { EmployeeId = 3, Name = "SSSS", Gender = "Male" }); 
        listEmployees.Add(new Employee { EmployeeId = 4, Name = "EE", Gender = "Female" }); 
        listEmployees.Add(new Employee { EmployeeId = 5, Name = "EEEE", Gender = "Female" }); 
        listEmployees.Add(new Employee { EmployeeId = 6, Name = "TTT", Gender = "Male" }); 
        listEmployees.Add(new Employee { EmployeeId = 7, Name = "FFF", Gender = "Male" }); 
        listEmployees.Add(new Employee { EmployeeId = 8, Name = "GGG", Gender = "Male" }); 
    } 
    
    // Custom indexer by EmployeeId
    public string this[int employeeId] { 
        get { 
            return listEmployees.FirstOrDefault(x => x.EmployeeId == employeeId).Name; 
        } 
        set { 
            listEmployees.FirstOrDefault(x => x.EmployeeId == employeeId).Name = value; 
        } 
    } 
} 

class Program { 
    public static void Main() { 
        Company company = new Company(); 
        Console.WriteLine("Name of Employee with Id = 2: " + company[2]); 
        Console.WriteLine("Name of Employee with Id = 5: " + company[5]); 
        Console.WriteLine("Name of Employee with Id = 8: " + company[8]); 
        System.Console.WriteLine(); 
        Console.WriteLine("Changing names of employees with Id = 2,5,8"); 
        company[2] = "Employee 2 Name Changed"; 
        company[5] = "Employee 5 Name Changed"; 
        company[8] = "Employee 8 Name Changed"; 
        System.Console.WriteLine(); 
        Console.WriteLine("Name of Employee with Id = 2: " + company[2]); 
        Console.WriteLine("Name of Employee with Id = 5: " + company[5]); 
        Console.WriteLine("Name of Employee with Id = 8: " + company[8]); 
        
        // C# 8.0 Index from end (^ operator)
        company.listEmployees[^2].Name = "Employee 2 Name Changed using new Syntax"; 
        company.listEmployees[^5].Name = "Employee 5 Name Changed using new Syntax"; 
        company.listEmployees[^8].Name = "Employee 8 Name Changed using new Syntax"; 
        
        System.Console.WriteLine(); 
        Console.WriteLine("Name of Employee with Id = 2: " + company.listEmployees[^2].Name); 
        Console.WriteLine("Name of Employee with Id = 5: " + company.listEmployees[^5].Name); 
        Console.WriteLine("Name of Employee with Id = 8: " + company.listEmployees[^8].Name); 
        Console.ReadLine(); 
    } 
}

Output

Name of Employee with Id = 2: SSS
Name of Employee with Id = 5: EEEE
Name of Employee with Id = 8: GGG
Changing names of employees with Id = 2,5,8
Name of Employee with Id = 2: Employee 2 Name Changed
Name of Employee with Id = 5: Employee 5 Name Changed
Name of Employee with Id = 8: Employee 8 Name Changed
Name of Employee with Id = 2: Employee 2 Name Changed using new Syntax
Name of Employee with Id = 5: Employee 5 Name Changed using new Syntax
Name of Employee with Id = 8: Employee 8 Name Changed using new Syntax

Index từ cuối (^ Operator) chi tiết

var array = new[] { "A", "B", "C", "D", "E" }; // Length = 5

// Index từ đầu (0-based)
array[0]  // "A"
array[1]  // "B"
array[4]  // "E"

// Index từ cuối (^ operator) - 1-based từ cuối
array[^1] // "E" (last)
array[^2] // "D" (second to last)
array[^5] // "A" (first)

// ^0 = Length (out of bounds!)
// array[^0] throws IndexOutOfRangeException

Range Operator (..) - C# 8.0

Kết hợp với ^ operator để slice collections:

var array = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

// Range syntax: start..end (end exclusive)
var slice1 = array[2..5];      // [2, 3, 4] - index 2,3,4
var slice2 = array[..3];       // [0, 1, 2] - từ đầu đến 3
var slice3 = array[5..];       // [5, 6, 7, 8, 9] - từ 5 đến cuối
var slice4 = array[^3..^0];    // [7, 8, 9] - 3 cuối (^0 = Length)
var slice5 = array[..];        // [0..9] - copy toàn bộ

// Range variable
Range range = 2..5;
var slice6 = array[range];     // [2, 3, 4]

Index và Range Structs

// Index struct
Index i1 = 2;       // Từ đầu
Index i2 = ^2;      // Từ cuối
int pos = i2.GetOffset(array.Length); // Convert to int index

// Range struct
Range r1 = 1..4;    // Start inclusive, end exclusive
Range r2 = ..3;     // Từ đầu đến 3
Range r3 = 2..;     // Từ 2 đến cuối
Range r4 = ^3..^0;  // 3 phần tử cuối

// Sử dụng với custom indexer
public class MyCollection {
    public T this[Index index] => _items[index.GetOffset(_items.Length)];
    public IEnumerable this[Range range] => _items[range.Start.GetOffset(_items.Length)..range.End.GetOffset(_items.Length)];
}

Custom Indexer trong Class

public class Matrix {
    private readonly double[,] _data;
    
    public Matrix(int rows, int cols) {
        _data = new double[rows, cols];
    }
    
    // 2D Indexer
    public double this[int row, int col] {
        get => _data[row, col];
        set => _data[row, col] = value;
    }
    
    // Row accessor returning Range
    public double[] this[Index row] {
        get {
            var r = row.GetOffset(_data.GetLength(0));
            var cols = _data.GetLength(1);
            var result = new double[cols];
            for (int c = 0; c < cols; c++) result[c] = _data[r, c];
            return result;
        }
    }
}