개발/C#

[Effective C#] nameof() 연산자

huiyu 2021. 1. 24. 14:18

nameof() - MS Link

변수, 형식 또는 멤버의 이름을 문자열 상수로 가져온다.

Console.WriteLine(nameof(System.Collections.Generic));  // output: Generic
Console.WriteLine(nameof(List<int>));  // output: List
Console.WriteLine(nameof(List<int>.Count));  // output: Count
Console.WriteLine(nameof(List<int>.Add));  // output: Add

var numbers = new List<int> { 1, 2, 3 };
Console.WriteLine(nameof(numbers));  // output: numbers
Console.WriteLine(nameof(numbers.Count));  // output: Count
Console.WriteLine(nameof(numbers.Add));  // output: Add

nameof() 연산자는 심볼 그 자체를 해당 심볼에 해당하는 문자열로 대체해준다. nameof()연산자를 사용하면 속성의 이름을 변경할 경우에도 전달되는 인자도 쉽게 변경할 수 있어 코드 유지보수에 좀더 효율적이라는 장점을 갖고 있다.

활용1) 인수검사 코드

public string Name
{
    get => name;
    set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
}

활용 2) INotifyPropertyChanged 인터페이스 구현 - 속성의 인수

public string Name
{
  get
  {
    return name;
  }
  set
  {
    if (value != name)
    {
      name = value;
      PropertyChanged?.Invoke(this,
        new PropertyChangedEventArgs(nameof(Name)));
    }
  }
}

private string name;

활용 3) 열거형 문자의 이름

public class NameOfOperation
{
    enum MyEnum { START, SECOND, THIRD, END };
 
    void WriteEnum()
    {
        Console.WriteLine(MyEnum.SECOND.ToString());
 
        Console.WriteLine(nameof(MyEnum.SECOND));
    }
}

 - ToString()을 사용시 프로그램은 런타임에 enum의 값을 가져온다. nameof()를 사용할 경우 컴파일 시점에 이름을 결정함으로 좀더 성능에 이점이 있다.

특징

* nameof()는 심볼의 이름을 평가하며, 타입, 변수, 인터페이스 ,네임스페이스에 대하여 사용할 수 있다. 완전히 정규화된 이름을 사용할 수도 있지만 정규화되지 않은 이름도 제한 없이 사용할 수 있다. 다만 제네릭 타입을 사용할 경우에는 부분적으로 제약이 있어서 모든 타입 매개변수를 지정한 닫힌 제네릭 타입만을 사용할 수 있다.

- 열린 제네릭 타입 (ex. Dictionary<Tkey, Tvalue>) : 아직 결정되지 않은 타입 파라미터가 있다
- 닫힌 제네릭 타입 (ex. Dircionary <string, int>) : 모든 파라미터가 정해짐

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

728x90
반응형