6

我最近开始尝试使用 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;
    }
}
4

3 回答 3

5

您可以使用 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);
        }
    }
于 2010-03-07T18:46:27.900 回答
3

另一种简单的方法,使用:

[NotifyPropertyChanged(AttributeExclude=true)]

...抑制特定方法的属性。即使有一个全局属性附加到类(如上面的示例中),这也有效。

这是完整的示例代码:

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

    public double ModifiedValue { get; private set; }

    [NotifyPropertyChanged(AttributeExclude=True)]
    public double OnlySetOnce { get; private set; }

    public MyClass()
    {
        OnlySetOnce = 1.0;
    }
}

添加此行后,PostSharp 甚至会更新 MSVS GUI 以删除指示哪些属性附加到方法的下划线。当然,如果您运行调试器,它将跳过执行该特定方法的任何属性。

于 2010-11-02T18:29:05.647 回答
0

仅供参考,我对 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 为空。

于 2010-03-09T03:45:12.397 回答