Example implementation of weak events using .NET&#

2019-03-11 22:44发布

问题:

Is there an example implementation of weak events using .NET's WeakEventManager?

I'm trying to implement it by following the "Notes to Inheritors" in the documentation, but it is vague. For example, I can't figure out how to call ProtectedAddListener from my static AddListener function in my custom manager.

回答1:

I figured it out on my own following the guidelines in the "Notes for Inheritors" section of the WeakEventManager documentation. Here's a basic implementation of WeakEventManager. The class sourcing the event is named PropertyValue and the event is named Changed.

public class PropertyValueChangedEventManager : WeakEventManager
{
    public static PropertyValueChangedEventManager CurrentManager
    {
        get
        {
            var manager_type = typeof(PropertyValueChangedEventManager);
            var manager = WeakEventManager.GetCurrentManager(manager_type) as PropertyValueChangedEventManager;

            if (manager == null)
            {
                manager = new PropertyValueChangedEventManager();
                WeakEventManager.SetCurrentManager(manager_type, manager);
            }

            return manager;
        }
    }

    public static void AddListener(PropertyValue source, IWeakEventListener listener)
    {
        CurrentManager.ProtectedAddListener(source, listener);
    }

    public static void RemoveListener(PropertyValue source, IWeakEventListener listener)
    {
        CurrentManager.ProtectedRemoveListener(source, listener);
    }

    protected override void StartListening(object source)
    {
        ((PropertyValue)source).Changed += DeliverEvent;
    }

    protected override void StopListening(object source)
    {
        ((PropertyValue)source).Changed -= DeliverEvent;
    }
}


回答2:

Sharp Observation is an open source project that has an easy to use implementation. You might want to take a look at their code or just use it as-is.

Usage

The MakeWeak() method returns a new delegate which invokes the same target as the original delegate, but holds a weak reference to the target so that the listener is not kept alive by the delegate:

var handler= new PropertyChangingEventHandler(listener.HandleChange);
observable.PropertyChanging += handler.MakeWeak<PropertyChangingEventHandler>();

Limitations

The current implementation has the following restrictions on delegates:

  • Return values are not supported.
  • Arguments of Out and Ref are not supported.