Подавление многоадресной передачи PostSharp с атрибутом

Я недавно начал экспериментировать с PostSharp, и я нашел, что особенно полезный аспект автоматизировал реализацию INotifyPropertyChanged. Вы видите пример здесь. Основная функциональность превосходна (все свойства будут уведомлены), но существуют случаи, где я мог бы хотеть подавить уведомление.

Например, я мог бы знать, что особое свойство установлено однажды в конструкторе и никогда не будет изменяться снова. По сути, нет никакой потребности испустить код для NotifyPropertyChanged. Издержки минимальны, когда классы не часто инстанцируют, и я могу предотвратить проблему путем переключения от автоматически сгенерированного свойства до поддержанного полем свойства и записи в поле. Однако, поскольку я изучаю этот новый инструмент, было бы полезно знать, существует ли способ отметить свойство с атрибутом для подавления генерации кода. Я хотел бы смочь сделать что-то вроде этого:

[NotifyPropertyChanged]
public class MyClass
{
    public double SomeValue { get; set; }

    public double ModifiedValue { get; private set; }

    [SuppressNotify]
    public double OnlySetOnce { get; private set; }

    public MyClass()
    {
        OnlySetOnce = 1.0;
    }
}

6
задан Dan Bryant 7 March 2010 в 18:03
поделиться

2 ответа

Вы можете использовать MethodPointcut вместо MulticastPointcut, то есть использовать Linq-over-Reflection и фильтровать PropertyInfo.IsDefined (ваш атрибут).

  private IEnumerable<PropertyInfo> SelectProperties( Type type )
    {
        const BindingFlags bindingFlags = BindingFlags.Instance | 
            BindingFlags.DeclaredOnly
                                          | BindingFlags.Public;

        return from property
                   in type.GetProperties( bindingFlags )
               where property.CanWrite &&
                     !property.IsDefined(typeof(SuppressNotify))
               select property;
    }

    [OnLocationSetValueAdvice, MethodPointcut( "SelectProperties" )]
    public void OnSetValue( LocationInterceptionArgs args )
    {
        if ( args.Value != args.GetCurrentValue() )
        {
            args.ProceedSetValue();

           this.OnPropertyChangedMethod.Invoke(null);
        }
    }
5
ответ дан 16 December 2019 в 21:38
поделиться

К вашему сведению, у меня были некоторые проблемы с примером на веб-сайте Sharpcrafters, и мне пришлось внести следующие изменения:

    /// <summary>
    /// Field bound at runtime to a delegate of the method <c>OnPropertyChanged</c>.
    /// </summary>
    [ImportMember("OnPropertyChanged", IsRequired = true, Order = ImportMemberOrder.AfterIntroductions)]
    public Action<string> OnPropertyChangedMethod;

Я думаю, что он вводил элемент OnPropertyChanged, но импортировал до него имел шанс быть создан. Это приведет к сбою OnPropertySet, потому что this.OnPropertyChangedMethod имеет значение null.

0
ответ дан 16 December 2019 в 21:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: