본문 바로가기
3.2 .net/C#

[.net/C#] CallerMemberName

by Dohi._. 2024. 9. 19.
728x90

[CallerMemberName]

CallerMemberName은 메서드가 호출된 위치의 메서드의 이름을 자동으로 가져오는 기능입니다.

주로 이벤트 또는 속성 변경 알림을 구현할 때 유용하다.

 

주요 특징으로는

자동 할당, 기본값 null, 코드 간결성이 있다.

 

  1.  자동할당
    • 메서드의 이름이 자동으로 할당이 되기 때문에 나중에 속성 이름을 변경하여도 호출부분을 수정할 필요가 없다 즉, 유지보수성에 좋고 문자열을 직접입력하여 발생할 수 있는 오타를 줄일 수 있다.
  2. 기본값 null
    • CallerMemberName은 기본값으로 null을 가지므로, 호출자가 매개변수를 제공하지 않아도 오류가 발생하지 않는다.
  3. 코드 간결성
    •  위에서도 말했듯 속성이름을 문자열로 명시할 필요가 없기 때문에 깔끔하고 유지보수하기 좋다.

 

예제를 들어 간단하게 설명을 하고 마무리 하도록 하겠습니다.

public class Person : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                //OnPropertyChanged("Name");  기존방식
                OnPropertyChanged(); // 여기서 CallerMemberName을 사용
            }
        }
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        // propertyName에 자동으로 "Name"이 할당됨
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

 

자 그래도 한번 해당 코드가 어떻게 작동하는지 자세하게 분석 해보겠습니다.

 

1. 클래스 정의 및 인터페이스 구현

public class Person : INotifyPropertyChanged

 

Person 클래스는 INotifyPropertyChanged 인터페이스를 구현하고 있고 해당 인터페이스는 구현하는 클래스가 속성이 변경될 때 이 이벤트를 발생시키고, 구독자는 이 이벤트를 구독하여 변화를 감지할 수 있게 제공한다.

 

2. 필드 및 속성 정의

private string _name;
public string Name
{
    get => _name;
    set
    {
        if (_name != value)
        {
            _name = value;
            OnPropertyChanged(); // 속성이 변경되었음을 알림
        }
    }
}

 

  • _name: 실제 데이터가 저장되는 private 필드.
  • Name: public 속성으로, 이 속성이 변경되면 OnPropertyChanged() 메서드를 호출해 속성 변경을 알림.

3. OnPropertyChanged 메서드

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

 

 

  • OnPropertyChanged: 이 메서드는 속성이 변경될 때 호출됨.
  • CallerMemberName: 메서드를 호출한 위치의 이름을 자동으로 가져옴. propertyName 매개변수에는 속성 이름이 자동으로 할당됨.

4. PropertyChanged 이벤트

public event PropertyChangedEventHandler PropertyChanged;

 

  • PropertyChanged: 속성이 변경되었음을 알리기 위해 정의된 이벤트.
  • 이 이벤트는 PropertyChangedEventHandler 대리자를 사용하여 구독자에게 알림을 전달함.

5. 이벤트 발생

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  • PropertyChanged: INotifyPropertyChanged 인터페이스에서 정의된 이벤트로, 속성 변경 사항을 알리기 위해 사용됨.
  • ?.: 널 조건 연산자. PropertyChanged가 null이 아닐 경우에만 Invoke를 호출하도록 하여, 구독자가 없는 경우에 대한 안전성을 제공함.
  • Invoke(this, new PropertyChangedEventArgs(name)): 현재 인스턴스(this)와 변경된 속성의 이름을 포함하는 PropertyChangedEventArgs 객체를 생성하여 이벤트를 발생시킴.

6. 구독자 측

구독자는 PropertyChanged 이벤트를 수신하여 속성이 변경되었음을 알 수 있다.

예를 들어, UI에서 DataContext로 사용될 때 속성 변경을 반영할 수 있다.

 

구독예제

public class ViewModel
{
    private Person _person;

    public ViewModel()
    {
        _person = new Person();
        _person.PropertyChanged += OnPersonPropertyChanged;
    }

    private void OnPersonPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(Person.Name))
        {
            // Name 속성이 변경되었을 때 처리할 로직
            Console.WriteLine("Name has changed!");
        }
    }
}

 

Name이 바뀌었을때 콘솔에 Name has changed!가 뜨게 될 것이다

 

이번에는 예제로 CallerMemberName에 대해서 알아봤습니다.

이벤트에 대한 앞선 포스팅이 없어 이벤트에 대해서도 자세하게 적어봤습니다.

감사합니다:)

728x90

댓글