The `this` 키워드

The this 키워드

한 클래스 안에 같은 이름을 가진 변수가 여러 개 있으면 어느 쪽을 가리키는지 모호해질 때가 있어요. 이럴 때 this가 어느 쪽을 가리킬지 바로잡아 주는 역할을 해요. this는 클래스의 현재 인스턴스, 그러니까 지금 작업하고 있는 그 객체 자신을 가리키는 키워드예요. 그런데 같은 키워드가 확장 메서드의 첫 번째 매개변수 앞에 붙는 수식자(modifier)로도 쓰이니까, 어디에 쓰이는지에 따라 역할이 조금 달라진다는 점만 기억해 두시면 좋아요.

[!NOTE] 이 문서는 현재 멤버 안에서 this가 '수신자(receiver) 인스턴스'를 가리키는 용법을 다뤄요. 확장 메서드에서의 쓰임은 별도 페이지에서 따로 설명하니까, 궁금하시면 extension 키워드 문서를 참고해 주세요.

C#을 처음 접하셨을 땐 더 큰 그림이 먼저 보이도록, this가 나오는 버전부터 확인해 볼게요. (이 문서에서 다루는 동작은 C#의 가장 초기 버전에서부터 존재했던 기본 기능이에요.)

this가 주로 쓰이는 경우는 크게 세 가지예요.

  • 비슷한 이름에 가려진 멤버를 정확히 지정할 때. 예를 들어 매개변수 이름이 필드 이름과 같을 때, 어느 쪽을 말하는 건지 딱 집어줘요.

    namespace Example1 //for redefinition of Employee
    {
        public class Employee
        {
            private string alias;
            private string name;
    
            public Employee(string name, string alias)
            {
                // Use this to qualify the members of the class
                // instead of the constructor parameters.
                this.name = name;
                this.alias = alias;
            }
        }
    }
    

    생성자에 들어온 매개변수 name, alias와 같은 이름의 필드 name, alias가 있죠. 이대로는 둘 다 name이라서 어느 게 매개변수고 어느 게 필드인지 헷갈려요. this.name처럼 앞에 this를 붙여 주면 "이건 필드 쪽을 말하는 거야"라고 컴파일러에 명확히 알려주는 거예요.

  • 그 객체를 다른 메서드의 인자로 넘길 때. 지금 자기 자신을 통째로 전달하고 싶으면 그냥 this라고 쓰면 돼요.

    CalcTax(this);
    
  • 인덱서(indexer)를 선언할 때. 배열처럼 객체[인덱스] 형태로 접근하게 만들고 싶을 때 this로 인덱서를 정의해요. 아래 코드는 int[] array를 감싸는 인덱서로, getset에서 this[int param]이 곧바로 배열을 읽고 쓰는 모습을 볼 수 있어요.

    public int this[int param]
    {
        get => array[param];
        set => array[param] = value;
    }
    

이제 한 가지 짚고 넘어갈 게 있어요. 정적(static) 멤버 함수는 객체의 일부가 아니라 클래스 레벨에 존재해요. 객체가 없어도 부를 수 있죠. 그렇기 때문에 정적 메서드에는 this 포인터가 없어요. 정적 메서드 안에서 this를 쓰면 오류가 나니 주의하셔야 해요.

그럼 실제 코드로 조금 더 자연스럽게 이어서 볼게요. 아래 예시에서 매개변수 namealias는 같은 이름의 필드를 가려요. 여기서 this로 그 변수들이 Employee 클래스의 멤버라는 걸 명확히 지정하고, 또 마지막에 this를 그대로 다른 클래스에 속한 CalcTax 메서드의 인자로 넘기는 것까지 확인할 수 있어요.

class Employee
{
    private string name;
    private string alias;

    // Constructor:
    public Employee(string name, string alias)
    {
        // Use this to qualify the fields, name and alias:
        this.name = name;
        this.alias = alias;
    }

    // Printing method:
    public void printEmployee()
    {
        Console.WriteLine($"""
        Name: {name}
        Alias: {alias}
        """);
        // Passing the object to the CalcTax method by using this:
        Console.WriteLine($"Taxes: {Tax.CalcTax(this):C}");
    }

    public decimal Salary { get; } = 3000.00m;
}

class Tax
{
    public static decimal CalcTax(Employee E)=> 0.08m * E.Salary;
}

class Program
{
    static void Main()
    {
        // Create objects:
        Employee E1 = new Employee("Mingda Pan", "mpan");

        // Display results:
        E1.printEmployee();
    }
}
/*
Output:
    Name: Mingda Pan
    Alias: mpan
    Taxes: $240.00
 */

printEmployee 메서드를 보면 두 가지 용법이 한 코드에 다 들어 있어요. this.name, this.alias로 필드를 지정하는 부분과, Tax.CalcTax(this)로 객체 자신을 넘기는 부분이죠. CalcTaxEmployeeSalary에 세율을 곱한 값을 돌려주는데, this 덕분에 지금 그 임금을 계산할 주체가 어떤 직원인지 정확히 전달돼요.

더 알아보기

출처: The this keyword — Microsoft Learn