struct 대신 class를 써야할 때?

[제목] struct 대신 class를 써야할 때?

C#에서 간단한 데이타 구조를 표현할 때 종종 struct 를 사용한다. 함수 안에서 사용되는 struct는 Value 타입으로 스택에 생성되고, class는 Reference 타입으로 인스턴스가 힙에 생성된다. 이러한 구조적인 차이는 때로 실무 코딩상에서 버그를 발생시키곤 하는데, 여기서는 그것의 대표적인 한 예를 들고자 한다.

예를 들어, HR 이라는 클래스에 RaiseSalary()라는 메서드가 있다고 가정하자. 이 메서드는 Employee 객체를 받아들여, Employee.Salary라는 필드의 값을 증가시키고자 한다.

Employee emp = new Employee();
emp.Name = "Lee";
emp.Salary = 9000;

HR hr = new HR();
Console.WriteLine(emp.Salary); // Salary 인상전
hr.RaiseSalary(emp);
Console.WriteLine(emp.Salary); // 인상후

Employee는 직원이름과 급여를 갖는 간단한 데이타 구조체라고 가정하고, 다음과 같이 getter와 setter를 모두 가지고 있어서 읽기와 쓰기가 가능하다.
struct Employee
{
    public string Name { get; set; }
    public int Salary { get; set; }
}

class HR
{
    public void RaiseSalary(Employee emp)
    {
        emp.Salary = emp.Salary + 1000;
    }
}

하지만 여기서 RaiseSalary() 메서드는 9000+1000 즉 10000값을 리턴하기로 되어 있는데, 실제 출력값은 9000이 나온다. 무엇이 잘못된 것인가?

문제는 Employee가 struct 구조체라는 점이다. 첫부분에 언급한 바와 같이, struct는 Value 타입이고 로컬 변수로 사용되거나 함수간 파라미터로 전달될 때 스택에 생성된다. struct 객체가 메서드의 파라미터로 전달되면, 이는 전체 struct 멤버들을 복사하여 스택에 새로 복제본은 생성한다. 그리고 메서드에서 이 복제본의 값이 변경하더라도 메서드 리턴시 원본의 값의 변환에는 영항을 미치지 않는다.

이러한 문제점을 해결하기 위해서는 Employee를 struct에서 class로 변경해야 한다. 그러면, Employee 멤버들이 복제본으로 전달되지 않고 힙 상에 있는 객체의 레퍼런스(개념상 포인터)로 전달되므로 변경사항이 메서드 호출 후에서 유지되게 된다.



본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.