项目作者: SamuelEnglard

项目描述 :
Weak Delegates for .NET
高级语言: C#
项目地址: git://github.com/SamuelEnglard/weakdelegates.git
创建时间: 2016-10-16T04:00:24Z
项目社区:https://github.com/SamuelEnglard/weakdelegates

开源协议:MIT License

下载


Weak Delegates for .NET

While there are many systems out there for weak events/delegates in .NET they
generally suffer from one or more of the following flaws:

  1. They only work with System.EventHander and System.EventHander<T>.
  2. The leak memory that is only cleaned up sometimes if at all.
  3. Their syntax/usage is extremely different from using strong delegates.

Not liking these issue I’ve created this experiment repository where I can try
create a system that has none of those issues. Currently issue #1 is completely
solved, this system with work with any delegate type. Issue #2 is mostly there,
though there is work to be done. Issue #3 is sadly still unsolved.

API

  1. namespace WeakDelegates
  2. {
  3. // Usage is the same as System.Delegate.Combine(Delegate, Delegate);
  4. public static T Combine<T>(T a, T b) where T : class;
  5. // Usage is the same as System.Delegate.Remove(Delegate, Delegate);
  6. public static T Remove<T>(T source, T value) where T : class;
  7. // Allows removing weak delegates when you don't have access to the delegate field directly.
  8. public static void Remove<T>(object eventContainer, string eventName, T value) where T : class
  9. }

Documentation for the same named static methods on System.Delegate should be
the same. Only real difference is that I use generics and enforce that it must
be a delegate type at run-time instead of forcing you to do lots of casting.

The Remove<T>(object eventContainer, string eventName, T value) where T : class method can be used to unsubscribe weak delegates from events.

Example

  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.Collections.Specialized;
  4. using static System.Collections.Specialized.WeakDelegateHelpers;
  5. namespace WeakTest
  6. {
  7. class Program
  8. {
  9. private class TestClass
  10. {
  11. private DateTime created = DateTime.UtcNow;
  12. public void Handle(object sender, NotifyCollectionChangedEventArgs e)
  13. {
  14. Console.WriteLine(e.NewItems[0]);
  15. }
  16. }
  17. public static void Main()
  18. {
  19. ObservableCollection<int> collection = new ObservableCollection<int>();
  20. TestClass testInstance = new TestClass();
  21. // To subscribe
  22. collection.CollectionChanged += WeakDelegates.WeakDelegate.Combine<NotifyCollectionChangedEventHandler>(null, testInstance.Handle);
  23. // to unsubscribe
  24. WeakDelegates.WeakDelegate.Remove<NotifyCollectionChangedEventHandler>(collection, nameof(collection.CollectionChanged), testInstance.Handle);
  25. }
  26. }
  27. }

Why?

See The Problem With
Delegates

by Dustin Campbell.

Issues

  1. Runtime code generation means that this will not work with .NET Native. This
    can be solved in theory by having the dynamic methods created at compile
    time.
  2. Slower than strong delegates. Not much can be done here without writing raw
    IL instead of C#.