我想知道如何从事件中取消订阅匿名方法。
我已经检查了Unsubscribe anonymous method in C#,但我的情况略有不同。
我在匿名方法中访问本地函数变量。
代码如下
private static void Test(Object dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (dependencyPropertyChangedEventArgs.OldValue is ObservableCollection<object>)
{
(dependencyPropertyChangedEventArgs.OldValue as ObservableCollection<object>).CollectionChanged -=
(s, e) => SelectedItemsChanged(dependencyObject, e); // TO FIX event unbsubscription via anonymous delegate
}
if (dependencyPropertyChangedEventArgs.NewValue is ObservableCollection<object>)
{
(dependencyPropertyChangedEventArgs.NewValue as ObservableCollection<object>).CollectionChanged +=
(s, e) => SelectedItemsChanged(dependencyObject, e);
}
}
答案 0 :(得分:2)
您无法使用匿名代表执行此操作。 为了能够取消订阅,您必须使用通常的代表。
答案 1 :(得分:1)
新答案,现在问题已经改变
基本上,你不能。你的处理程序取决于dependencyObject
,它将在每个调用的新对象中捕获,因此你最终会得到不平等的委托。
您可以创建一个新类,其中包含依赖项对象并覆盖Equals
以比较这些对象而不是使用匿名函数,或者您可以只保留对先前订阅的引用处理程序。
旧答案,当代表不依赖参数时
奇怪的是,在这种特殊情况下,看起来你没有捕获任何局部变量。所以,可能如果您正在订阅该事件的仅地点来自此方法,那么您可以放弃:
private static void Test(Object a, DependencyPropertyChangedEventArgs args)
{
NotifyCollectionChangedEventHandler handler =
(s, e) => SelectedItemsChanged(dependencyObject, e);
var oldObservable = args.OldValue as ObservableCollection<object>;
if (oldObservable != null)
{
oldObservable.CollectionChanged -= handler;
}
var newObservable = args.NewValue as ObservableCollection<object>;
if (newObservable != null)
{
newObservable.CollectionChanged += handler;
}
}
由于您现在只有一个 lambda表达式,我希望将其转换为单个静态方法,因此新创建的委托将等于原始委托。< / p>
但是,我不会推荐。我只是自己创建方法,然后使用方法组转换。