{"id":20936935,"url":"https://github.com/shmuelie/weakdelegates","last_synced_at":"2025-07-01T05:04:33.045Z","repository":{"id":149309132,"uuid":"71029052","full_name":"shmuelie/weakdelegates","owner":"shmuelie","description":"Weak Delegates for .NET","archived":false,"fork":false,"pushed_at":"2023-05-28T23:02:16.000Z","size":44,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-28T22:24:42.915Z","etag":null,"topics":["concept","delegate","dot-net","dotnet","weak-delegates"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shmuelie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-10-16T04:00:24.000Z","updated_at":"2023-05-28T23:02:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"6e27a61f-1dc2-424f-b021-275a5cb4c488","html_url":"https://github.com/shmuelie/weakdelegates","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/shmuelie/weakdelegates","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shmuelie%2Fweakdelegates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shmuelie%2Fweakdelegates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shmuelie%2Fweakdelegates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shmuelie%2Fweakdelegates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shmuelie","download_url":"https://codeload.github.com/shmuelie/weakdelegates/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shmuelie%2Fweakdelegates/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262900084,"owners_count":23381657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concept","delegate","dot-net","dotnet","weak-delegates"],"created_at":"2024-11-18T22:30:17.771Z","updated_at":"2025-07-01T05:04:33.036Z","avatar_url":"https://github.com/shmuelie.png","language":"C#","readme":"# Weak Delegates for .NET\n\nWhile there are many systems out there for weak events/delegates in .NET they\ngenerally suffer from one or more of the following flaws:\n\n1. They only work with `System.EventHander` and `System.EventHander\u003cT\u003e`.\n2. The leak memory that is only cleaned up sometimes if at all.\n3. Their syntax/usage is extremely different from using strong delegates.\n\nNot liking these issue I've created this experiment repository where I can try\ncreate a system that has none of those issues. Currently issue #1 is completely\nsolved, this system with work with any delegate type. Issue #2 is mostly there,\nthough there is work to be done. Issue #3 is sadly still unsolved.\n\n## API\n\n```csharp\nnamespace WeakDelegates\n{\n    // Usage is the same as System.Delegate.Combine(Delegate, Delegate);\n    public static T Combine\u003cT\u003e(T a, T b) where T : class;\n    // Usage is the same as System.Delegate.Remove(Delegate, Delegate);\n    public static T Remove\u003cT\u003e(T source, T value) where T : class;\n    // Allows removing weak delegates when you don't have access to the delegate field directly.\n    public static void Remove\u003cT\u003e(object eventContainer, string eventName, T value) where T : class\n}\n```\n\nDocumentation for the same named static methods on `System.Delegate` should be\nthe same. Only real difference is that I use generics and enforce that it must\nbe a delegate type at run-time instead of forcing you to do lots of casting.\n\nThe `Remove\u003cT\u003e(object eventContainer, string eventName, T value) where T :\nclass` method can be used to unsubscribe weak delegates from events.\n\n### Example\n\n```csharp\nusing System;\nusing System.Collections.ObjectModel;\nusing System.Collections.Specialized;\nusing static System.Collections.Specialized.WeakDelegateHelpers;\n\nnamespace WeakTest\n{\n    class Program\n    {\n        private class TestClass\n        {\n            private DateTime created = DateTime.UtcNow;\n\n            public void Handle(object sender, NotifyCollectionChangedEventArgs e)\n            {\n                Console.WriteLine(e.NewItems[0]);\n            }\n        }\n\n        public static void Main()\n        {\n            ObservableCollection\u003cint\u003e collection = new ObservableCollection\u003cint\u003e();\n            TestClass testInstance = new TestClass();\n            // To subscribe\n            collection.CollectionChanged += WeakDelegates.WeakDelegate.Combine\u003cNotifyCollectionChangedEventHandler\u003e(null, testInstance.Handle);\n            // to unsubscribe\n            WeakDelegates.WeakDelegate.Remove\u003cNotifyCollectionChangedEventHandler\u003e(collection, nameof(collection.CollectionChanged), testInstance.Handle);\n        }\n    }\n}\n\n```\n\n## Why?\n\nSee [The Problem With\nDelegates](https://web.archive.org/web/20150327023026/http://diditwith.net/PermaLink,guid,fcf59145-3973-468a-ae66-aaa8df9161c7.aspx)\nby [Dustin Campbell](https://twitter.com/dcampbell).\n\n## Issues\n\n1. Runtime code generation means that this will not work with .NET Native. This\n   can be solved in theory by having the dynamic methods created at compile\n   time.\n2. Slower than strong delegates. Not much can be done here without writing raw\n   IL instead of C#.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshmuelie%2Fweakdelegates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshmuelie%2Fweakdelegates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshmuelie%2Fweakdelegates/lists"}