C# 8.0의 ^ 연산자(끝부터 인덱스)란?
C# 8.0에서 새롭게 도입된 ^ 연산자는 '끝부터 인덱스(index from end)' 연산자라고 부릅니다. 이 연산자는 시퀀스나 컬렉션의 끝을 기준으로 한 상대적 인덱스를 반환합니다.
기존에는 컬렉션의 뒤쪽 요소에 접근하려면 list[list.Count - 1]처럼 전체 개수를 먼저 계산한 뒤 역순으로 접근해야 했습니다. 반면 ^ 연산자를 사용하면 list[^1]처럼 훨씬 간결하고 직관적으로 끝쪽 요소에 접근할 수 있어, 기존 방식보다 가장 compact하고 쉬운 방법으로 평가받습니다.
참고: ^1은 마지막 요소를, ^2는 뒤에서 두 번째 요소를 의미합니다.
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";
예제 코드
다음 예제는 C#의 인덱서(Indexer)를 정의해 사원 ID로 이름을 조회하고 수정하는 방법과, ^ 연산자를 이용해 리스트의 끝에서부터 요소에 접근하는 방법을 함께 보여줍니다.
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" });
}
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]);
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();
}
}실행 결과
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
정리
인덱서는 this[int] 형태로 정의되며, get/set 접근자를 통해 객체를 배열처럼 다룰 수 있게 해 줍니다. 여기에 C# 8.0의 ^ 연산자를 함께 활용하면 컬렉션의 길이를 별도로 계산하지 않고도 끝에서부터 손쉽게 요소를 읽거나 수정할 수 있어 코드의 가독성과 생산성이 크게 향상됩니다.