C# InotifyProperty已更改订阅自

C# InotifyProperty已更改订阅自,c#,.net,inotifypropertychanged,C#,.net,Inotifypropertychanged,我有一个实现INotifyPropertyChanged的类。我使用Simon Cropp的优秀工具将INotifyPropertyChanged代码注入属性。但是,我现在需要修改一组属性的setter,以便在集合完成后都执行相同的操作。修改setter需要创建支持字段、实现get、实现set等,除了支持字段的名称之外,所有实现都是相同的。我只是通过使用来避免所有这些 相反,我可以让我的类订阅它自己的PropertyChanged事件,并在事件处理程序中处理更改后的操作。这样做安全吗?我意识到如

我有一个实现INotifyPropertyChanged的类。我使用Simon Cropp的优秀工具将INotifyPropertyChanged代码注入属性。但是,我现在需要修改一组属性的setter,以便在集合完成后都执行相同的操作。修改setter需要创建支持字段、实现get、实现set等,除了支持字段的名称之外,所有实现都是相同的。我只是通过使用来避免所有这些

相反,我可以让我的类订阅它自己的PropertyChanged事件,并在事件处理程序中处理更改后的操作。这样做安全吗?我意识到如果我的操作修改了我正在监视的一个属性,我将不得不小心无限递归导致堆栈溢出。我还需要注意其他问题吗

这里有一个例子

public class Foo : INotifyPropertyChanged{
    public event PropertyChangedEventHandler PropertyChanged;

    public Prop1 { get; set; }
    public Prop2 { get; set; }
    public Prop3 { get; set; }
    public Prop4 { get; set; }

    public Foo(){
        this.PropertyChanged +=
            new PropertyChangedEventHandler(Foo_PropertyChanged);
    }

    private void Foo_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "Prop1":
            case "Prop2":
            case "Prop3":
                DoSomething();
                break;
            case "Prop4":
                DoSomethingElse();
                break;
        }
    }

    private void DoSomething()
    {
        ....
    }

    private void DoSomethingElse()
    {
        ....
    }
}
编辑

请指出,我不需要订阅该活动。我已经允许NotifyPropertyWeaver注入OnPropertyChanged。相反,我可以实现onProperty改变自己来完成同样的事情

更新代码:

public class Foo : INotifyPropertyChanged{
    public event PropertyChangedEventHandler PropertyChanged;

    public Prop1 { get; set; }
    public Prop2 { get; set; }
    public Prop3 { get; set; }
    public Prop4 { get; set; }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
        switch (propertyName)
        {
            case "Prop1":
            case "Prop2":
            case "Prop3":
                DoSomething();
                break;
            case "Prop4":
                DoSomethingElse();
                break;
        }
    }

    private void DoSomething()
    {
        ....
    }

    private void DoSomethingElse()
    {
        ....
    }
}

我已经做了这个/使用了以前做过的代码,并且没有注意到代码方面的重大副作用。根据属性的数量,您可能会看到性能下降,但可能会很小。我所注意到的是,在查看代码时,并不总是立即清楚为什么使用此模式会产生效果。你需要注意的是你如何设计你的类。当您快速组合类时,自动属性很好,但它们可能会成为您总体设计的障碍。我通常不使用它们,除非它是一个对象的快速模型,或者是我用来传输数据的一个非常简单的对象。你必须问自己的问题是,你这样设计你的对象是因为它最适合你的代码、程序、风格,还是因为你试图使用一个特定的特性,即自动属性

有一件事要考虑的是,你会对每一个领域采取同样的行动,或者你会采取不同的行动吗?如果你有不同的行动,你很快就会得到一个大而笨拙的方法。如果它们是相同的操作,则可能更容易管理


我实现
INotifyProperty
接口的正常方法是创建一个方法,该方法更改字段,执行通知,还可以在更改后执行
操作。这避免了所有大的条件语句,并提供了对操作的细粒度控制,但有足够的细粒度控制来完全灵活。如果我创建了很多相关的对象,我通常也会创建一个基类来继承所有这些对象,并将此更改方法作为受保护的方法,这样我就不必为每个类重新实现一次模式。

首先,您只需实现OnPropertyChanged,而不必使用事件

其次,这被认为是不好的形式。NotifyPropertyWeaver在代码中执行大量检查,并检测属性之间的依赖关系。例如,如果在属性B的代码中使用属性A,NotifyPropertyWeaver将在A的代码中为B添加第二个OnPropertyChanged,以确保所有内容都已更新


简而言之,不要这样做,把所有的内容都输入出来。

我已经添加了一个On_PropertyName_Changed功能来NotifyPropertyWeaver

所以如果你写这个

public class Foo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
    public string Prop4 { get; set; }

    void OnProp3Changed()
    {
    }

    void OnProp4Changed()
    {
    }
}

对OnProp3Changed和OnProp4Changed的调用将分别注入到Prop3和Prop4的集合中。

自动属性如何阻碍设计?如果你需要向一个getter或setter添加逻辑/检查,难道你不简单地创建一个backing字段并将属性扩展到一个显式实现吗?@Aydsman我想说的是,如果你围绕它们进行设计以保持它们,而不是用backing字段替换它们,它们可能会成为一个障碍。当你不需要一个支持域时,它们是伟大的(爱它们),但你不应该仅仅因为你想使用它们而避免创建支持域。你能给我指一下你上面提到的行动方法的任何信息吗?@DarthChucks该模式不是来自任何地方,而是从经验和需要中有机地发展而来。我肯定有人在什么地方写过,只是我脑子里没有关于它的参考资料。如果你想要一个如何实现它的例子,我可以提供。我明白了。抱歉,我不是从你的帖子里得到的。我绝对同意,;为了保留自动属性而进行的黑客攻击是愚蠢和危险的。自动属性的美妙之处在于,您可以在不破坏API兼容性的情况下扩展它们。很好的一点是,如果我显式实现OnPropertyChanged,而不是期望NotifyPropertyWeaver为我执行此操作,则无需订阅事件。我同意NotifyPropertyWeaver将处理属性之间的依赖关系。然而,这不是我想要实现的。拥有10个类,每个类包含5个属性,除了支持字段名之外,所有这些属性都具有完全相同的12行实现,这不仅单调乏味,而且容易出错。我希望使内容更易于阅读和维护,这就是我使用NotifyPropertyWeaver的原因。有几件事你可以试试。PostSharp将比NotifyPropertyWeaver更灵活。或者你可以试试内置的模板,我相信它叫做T4。或者使用代码片段生成代码。@Joel您能详细说明在这种情况下PostSharp比NPW更灵活吗?我很想知道我会是什么样的人missing@Simon可以做的不仅仅是改变InotifyProperty。可以找到一些具体的场景。您能提供一个更真实的代码示例,以便我更好地理解您与achive的联系吗?