如果事件处理程序不存在,如何恰好添加一次

时间:2013-11-20 17:27:39

标签: c# .net oop events

我需要在我的收藏更改中添加和删除事件处理程序:

public void SetStorageProviderFor<T>(Expression<Func<T, object>> expr, IStorageProvider sp) where T : class
{
    MemberExpression me = (MemberExpression)expr.Body;
    Set<T>().Local.CollectionChanged +=
        (sender, args) =>
        {
            foreach (var item in args.NewItems)
            {
                // get entity's property on member expression and set its value
            }
        }
}
  1. 如何阻止添加相同的处理程序?
  2. 如何删除某些特定处理程序?我不认为我应该重复所有相同的代码,但使用“ - =”标记...
    我还尝试将处理程序设为Action以将其存储在内存中,并随时从CollectionChanged取消分配:

    Action<object, NotifyCollectionChangedEventArgs> act = (sender, args) => { }

  3. 但是CollectionChanged无法接受此Action作为处理程序:(
    任何帮助表示赞赏 的更新
    我道歉,我发布了更多真实的代码。问题是我的处理程序使用的参数多于CollectionChanged的参数,还需要expr方法的spSetStorageProviderFor。在这种情况下,我可以创建命名方法作为Tim S.建议,但如果我提供额外的参数,那么我将无法直接将其分配给Set<T>().Local.CollectionChanged,将再次需要匿名lambda;(

1 个答案:

答案 0 :(得分:2)

我建议您保留一些内容以匹配T到您的上一个处理程序,例如字典。我正在使用static字典,但是如果实例是需要的话,那么(这是这种类型和T的组合,而不仅仅是静态T,那就赢了“ t附加多个处理程序)将其更改为。

为了从事件中删除处理程序,您需要使用-=并且它需要匹配首次添加的委托。它equates the delegates使用了创建的对象的实例等。由于lambda(以及从中生成的类/方法)的复杂性,这将很难重新创建,因此以您可以引用的方式存储旧值更容易。

private static Dictionary<Type, NotifyCollectionChangedEventHandler> handlers =
           new Dictionary<Type, NotifyCollectionChangedEventHandler>();
public void SetStorageProviderFor<T>(Expression<Func<T, object>> expr,
                                     IStorageProvider sp) where T : class
{
    var local = Set<T>().Local;
    MemberExpression me = (MemberExpression)expr.Body;

    NotifyCollectionChangedEventHandler existing;
    if (handlers.TryGetValue(typeof(T), out existing))
    {
        local.CollectionChanged -= existing;
    }

    NotifyCollectionChangedEventHandler newHandler =
        (sender, args) =>
        {
            foreach (var item in args.NewItems)
            {
                // get entity's property on member expression and set its value
                // (uses expr and sp)
            }
        };
    local.CollectionChanged += newHandler;
    handlers[typeof(T)] = newHandler;
}