본문 바로가기
책/Effective C#

Effective C# - Item6 nameof() 연산자를 적극 활용하라

by 코딩하는 돼징 2023. 11. 19.
반응형

부산 시스템의 대중화로 인해 여러 시스템 간에 데이터를 주고 받아야하는 일이 늘어났다. 이는 서로 다른 플랫폼과 다양한 언어로 개발된 프로그램 간에 데이터 교환의 필용성을 증가시키고 있다.

이름이나 문자열 식별자를 활용하는 간다한 라이브러리들이 이러한 차이를 극복하는데 사용된다. 방법은 간편하지만 그에 준하는 추가 비용이 발생하며 타입 정보 손실의 주요 단점을 가지고 있다. 이로 인해 동적 타입 언어의 유연성은 얻을 수 있지만 정적 타입 언어의 주요 장점 중 하나인 타입 정보를 활용한 개발 도구의 지원을 받지 못한다.


그렇게 탄생된 것이 nameof()라는 연산자이다.

 

nameof()연산자

프로그램의 요소의 이름을 문자열 형태로 변환하는 역할을 한다. 이를 이용하면 코드의 유지보수가 용이해지고 디버깅이 간편해진다.

 

장점

1. 리팩토링시 안전성

nameof를 사용하면 해당 이름을 문자열로 하드코딩하는 것보다 안전하게 변경이 가능하다. 만약 문자열로 하드코딩된 이름이 있다면 해당 ㅁ누자열을 변경하는 과정에서 오타가 발생할 수 있지만 nameof를 사용하면 컴파일러가 해당 이름의 유효성을 검사해준다.

가장 일반적인 활용의 예로 INotifyPropertyChanged 인터페이스의 구현부를 살펴보자


01 nameof을 사용하지 않는 경우

public class Person
{
    private string fullName;

    public string GetFullName()
    {
        return fullName;
    }

    public void SetFullName(string fn)
    {
        fullName = fn;
    }
}

02 nameof을 사용하는 경우

public class Person
{
    private string fullName;

    public string GetFullName()
    {
        return fullName;
    }

    public void SetFullName(string fn)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(fullName)));
    }
}

2. 디버깅 및 유지보수의 용이성

nameof를 사용하면 디버깅 메시지가 변수 이름을 출력하므로 변수가 변경되어도 메시지는 자동으로 업데이트된다. 그렇지 않으면 직접 문자열을 수정해야하기 때문에 불편하다.

01 nameof 사용하지 않는 경우

public class Calculator
{
    public int Add(int a, int b)
    {
        Console.WriteLine("Adding: " + a + ", " + b);
        return a + b;
    }
}

예시

Calculator calculator = new Calculator();
result = calculator1.Add(3, 5);

결과

Adding: 3, 5

02 nameof 사용하는 경우

public class Calculator
{
    public int Add(int a, int b)
    {
        Console.WriteLine("Adding: " + nameof(a) + ", " + nameof(b));
        return a + b;
    }
}

 

예시

Calculator calculator = new Calculator();
result = calculator.Add(3, 5);

결과

Adding: a, b

문자열을 하드코딩하는 대신 nameof()를 사용하면 rename작업을 수행할 때도 실수를 줄일 수 있다.

01 nameof() 사용하지 않은 경우

만약 변수의 이름을 변경해야 하는 경우, 변수를 참조하는 모든 곳에서 해당 이름을 일일이 찾아서 변경해야 한다. 이름이 하드코딩되어 있기 때문에 실수할 가능성이 크며, 이는 번거로운 프로세스일 수 있다.

public static void ExceptionMessage(object thisCantBeNull)
{
    if (thisCantBeNull == null)
        throw new ArgumentNullException("thisCantBeNULL",
            "We told you this cant be null");
}

02 nameof() 사용하는 경우

nameof(thisCantBeNull)을 사용하면 변수의 이름을 변경할 때마다 해당 이름을 일일이 찾아서 수정할 필요가 없다. nameof는 변수의 이름을 참조하므로 이름이 변경되면 자동으로 업데이트되어 유지보수성을 향상시킨다. 이것이 변수 이름을 문자열로 전달하는 것이 실수를 방지하고 코드 유지보수성을 높이는 이유다.

public static void ExceptionMessage(object thisCantBeNull)
{
    if(thisCantBeNull == null)
        throw new ArgumnetNullException(nameof(thisCantBeNULL),
            "We told you this cant be null");
}

 

 

 

결론

nameof()연산자를 사용하면 심볼의 이름을 완전히 바꾸거나 수정할 경우에도 손쉽게 그 변경사항을 반영할 수 있다. 정적 분석 도구를 이용하면 인자의 이름을 매개변수로 취하는 메서드를 사용할 때 저지르곤 하는 실수들을 미연에 방지할 수 있다.

 

 

 

 

 

 

본 게시글은 Effective C#을 읽고 정리하였습니다.

 

 

 

반응형

댓글