C# 带属性的PostSharp组播抑制

C# 带属性的PostSharp组播抑制,c#,wpf,postsharp,C#,Wpf,Postsharp,我最近开始尝试PostSharp,发现了一个特别有用的方面,可以自动实现INotifyPropertyChanged。你可以看到这个例子。基本功能非常出色(所有属性都将得到通知),但在某些情况下,我可能希望取消通知 例如,我可能知道某个特定属性在构造函数中设置了一次,并且永远不会再更改。因此,不需要发出NotifyPropertyChanged的代码。当类不经常实例化时,开销是最小的,我可以通过从自动生成的属性切换到字段支持的属性并写入字段来防止问题的发生。但是,在我学习这个新工具时,如果知道是

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

您可以使用MethodPointcut而不是MulticastPointcut,即使用Linq over Reflection并根据PropertyInfo.IsDefined(您的属性)进行过滤

private IEnumerable SelectProperties(类型)
{
const BindingFlags BindingFlags=BindingFlags.Instance|
BindingFlags.DeclaredOnly
|国旗。公众;
财产返还
在type.GetProperties(bindingFlags)中
where property.CanWrite&&
!property.IsDefined(typeof(SuppressNotify))
选择属性;
}
[OnLocationSetValueAdvice,方法切入点(“SelectProperties”)]
设置值上的公共无效(LocationInterceptionArgs args)
{
如果(args.Value!=args.GetCurrentValue())
{
args.ProceedSetValue();
this.OnPropertyChangedMethod.Invoke(null);
}
}

仅供参考,我对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方法的委托。
/// 
[ImportMember(“OnPropertyChanged”,IsRequired=true,Order=ImportMemberOrder.AfterIntroductions)]
关于财产的公共行动改变方法;

我认为它引入了OnPropertyChanged成员,但在它有机会被创建之前就已经导入了。这将导致OnPropertySet失败,因为此.OnPropertyChangedMethod为null。

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

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

非常好,谢谢。这是一个非常强大的工具,我的项目感觉非常干净,没有所有繁琐的INotifyPropertyChanged管道。
[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;
    }
}