Использование метаданных для получения ссылки на класс, вызывающий определенный метод

#c#

#c#

Вопрос:

При использовании INotifyPropertyChanged можно сделать что-то вроде этого, чтобы получить имя свойства, в котором был вызван метод, вызывающий событие.

  public void RaisePropertyChanged([CallerMemberName] string prop = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(new object(), new PropertyChangedEventArgs(prop));

        }

    }
  

Существует ли какой-либо другой тип атрибута, который можно использовать для получения ссылки на класс, содержащий это свойство? Я хочу иметь возможность вызывать RaisePropertyChanged() любое свойство из любого из моих классов viewmodel. Все мои классы viewmodel являются производными от базы, поэтому я думаю, что смогу сделать что-то подобное.

  public void RaisePropertyChanged([CallerMemberName] string prop = "", [CallerClassRef] VmBase base = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(base, new PropertyChangedEventArgs(prop));

        }

    }
  

Ответ №1:

Вызывается ключевое слово для доступа к текущей ссылке на класс this :

 public void RaisePropertyChanged([CallerMemberName] string prop = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}
  

Это будет работать независимо от того, сколько раз вы производите этот класс, this всегда экземпляр, на котором была вызвана эта функция.

Ответ №2:

Попробуйте использовать надстройку Fody — PropertyChanged. Это поможет вам внедрить реализацию INotifyPropertyChanged в IL-код.

Исходный код :

 [ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}
  

При компиляции

 public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
  

Исходный код скопирован из: https://github.com/Fody/PropertyChanged