【问题标题】:Suppressing PostSharp Multicast with Attribute使用属性抑制 PostSharp 多播
【发布时间】:2010-03-07 18:03:41
【问题描述】:

我最近开始尝试使用 PostSharp,我发现了一个特别有用的方面来自动实现 INotifyPropertyChanged。您可以查看示例here。基本功能非常出色(所有属性都会收到通知),但在某些情况下我可能想要禁止通知。

例如,我可能知道某个特定属性在构造函数中设置了一次,并且永远不会再更改。因此,无需发出 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;
    }
}

【问题讨论】:

    标签: c# wpf postsharp


    【解决方案1】:

    您可以使用 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);
            }
        }
    

    【讨论】:

    • 太好了,谢谢。这是一个非常强大的工具,我的项目感觉非常干净,没有所有繁琐的 INotifyPropertyChanged 管道。
    【解决方案2】:

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

    [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 以删除指示哪些属性附加到方法的下划线。当然,如果您运行调试器,它将跳过执行该特定方法的任何属性。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多