我有一个实现INotifyPropertyChanged的类。我正在使用Simon Cropp的优秀NotifyPropertyWeaver将INotifyPropertyChanged代码注入属性中。但是我现在需要修改一堆属性的setter,以便在set完成后对所有属性做同样的事情。修改setter需要创建支持字段,实现get,实现set等所有相同的实现,除了支持字段的名称。我只是通过使用NotifyPropertyWeaver避免了所有这一切。
相反,我可以让我的类订阅它自己的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()
{
....
}
}
修改
Joel Lucsy善意地指出我不需要订阅该活动。我一直在允许NotifyPropertyWeaver注入OnPropertyChanged。相反,我可以自己实现OnPropertyChanged来完成同样的事情。
更新的代码:
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()
{
....
}
}
答案 0 :(得分:1)
首先,您只需实现OnPropertyChanged,而不必使用该事件。
其次,这被认为是不好的形式。 NotifyPropertyWeaver会对代码进行大量检查,并检测属性之间的依赖关系。例如,如果在属性B的代码中使用属性A,NotifyPropertyWeaver将在A的代码中为B添加第二个OnPropertyChanged,以确保所有内容都已更新。
简而言之,不要这样做,输入所有内容。
答案 1 :(得分:0)
我已经完成了这个/使用过的代码,并且已经注意到没有很好的副作用代码。根据您可以看到性能影响的属性数量,但它可能会很小。我注意到的是,在查看代码时,为什么在使用此模式时会发生效果并不总是立即清楚。您需要注意的是如何设计课程。当你快速整理课程时,自动属性很好,但它们可能成为你所有设计的障碍。我通常不使用它们,除非它快速模拟一个对象或它是一个非常简单的对象,我用它来传输数据。您必须问自己的问题是,您是否以这种方式设计对象,因为它最适合您的代码,程序,样式,或者因为您尝试使用特定功能,即自动属性。
要考虑的一件事是,你是否会为每个领域做同样的动作,或者你会采取不同的行动?如果你有不同的行动,你很快就会得到一个笨重的方法。如果它们是相同的操作,则可能更容易管理。
我实现INotifyProperty
接口的正常方法是创建一个方法来更改字段,执行通知,并且还可以在更改后执行Action
。这避免了拥有所有大条件语句并对动作进行细粒度控制,但具有足够的细粒度控制以完全灵活。如果我正在创建大量相关的对象,我通常只是创建一个基类来继承所有这些对象,将此更改方法作为受保护的方法,因此我不必每次重新实现一次。类。
答案 2 :(得分:0)
我在NotifyPropertyWeaver中添加了一个On_PropertyName_Changed功能 http://code.google.com/p/notifypropertyweaver/wiki/On_PropertyName_Changed
所以,如果你写这个
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的集合中。