Nad*_*dya 7 c# extension-methods static-methods event-handling
我有一个扩展方法来订阅PropertyChanged实现的对象的事件INotifyPropertyChanged.
我希望事件只发一次.不多.
这是我的方法.
public static void OnPropertyChanged<T>(this INotifyPropertyChanged target, string propertyName, Action action)
{
if (target == null)
{
return;
}
PropertyChangedEventHandler handler = (obj, e) =>
{
if (propertyName == e.PropertyName)
{
action();
}
};
target.PropertyChanged -= handler;
target.PropertyChanged += handler;
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用.我无法删除事件处理程序,因此每次调用此方法时都会触发事件.
我尝试了不同的方法.而不是使用匿名方法,更传统的东西,像这样:
public static void OnPropertyChanged<T>(this INotifyPropertyChanged target, string propertyName, Action action)
{
if (target == null)
{
return;
}
target.PropertyChanged -= target_PropertyChanged;
target.PropertyChanged += target_PropertyChanged;
}
static void target_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//do stuff here
}
Run Code Online (Sandbox Code Playgroud)
它只是工作正常.该事件只触发一次,但我还需要Action参数.我不能用这种方法.
任何解决方法或不同的方法来解决这个问题?静态方法中的匿名方法有什么奇怪之处吗?
提前致谢.
这是使用匿名方法作为事件处理程序的限制。它们不能像普通方法一样被删除(从技术上讲,这是通过方法组转换自动创建的委托实例),因为匿名方法被编译到编译器生成的容器类中,并且每次都会创建该类的新实例。
为了保留操作参数,您可以创建一个容器类,其中包含事件处理程序的委托。该类可以在您正在使用的其他类的内部声明为私有,或者可以在“Helpers”命名空间中将其设置为内部类。它看起来像这样:
class DelegateContainer
{
public DelegateContainer(Action theAction, string propName)
{
TheAction = theAction;
PopertyName = propName;
}
public Action TheAction { get; private set; }
public string PropertyName { get; private set; }
public void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
if(PropertyName == e.PropertyName)
TheAction();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在类中创建并存储对容器的引用。您可以创建一个静态成员currentContainer,然后设置处理程序,如下所示:
private static DelegateContainer currentContainer;
public static void OnPropertyChanged<T>(this INotifyPropertyChanged target, string propertyName, Action action)
{
if (target == null)
{
return;
}
if(currentContainer != null)
target.PropertyChanged -= currentContainer.PropertyChangedHandler;
currentContainer = new DelegateContainer(action, propertyName);
target.PropertyChanged += currentContainer.PropertyChangedHandler;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1585 次 |
| 最近记录: |