using System.Collections.Generic;
public static void Main() {
MyClass myClass = new MyClass();
myClass.SubscribeOnce((s, e) => {});
myClass.Subscribe(MyDelegate);
myClass.Unsubscribe(MyDelegate);
public static void MyDelegate(object sender, MyClass.MyEventEventArgs e) {
private EventWrapper<MyEventEventArgs> myEvent = new EventWrapper<MyEventEventArgs>();
public void FireMyEvent() {
myEvent.Invoke(this, new MyEventEventArgs(1000, DateTime.Now));
public void SubscribeOnce(EventHandler<MyEventEventArgs> eventHandler) {
myEvent.SubscribeOnce(eventHandler);
public void Subscribe(EventHandler<MyEventEventArgs> eventHandler) {
myEvent.Subscribe(eventHandler);
public void Unsubscribe(EventHandler<MyEventEventArgs> eventHandler) {
myEvent.Unsubscribe(eventHandler);
public class MyEventEventArgs : EventArgs {
public DateTime MyDateTime;
public MyEventEventArgs(int myInt, DateTime myDateTime) {
internal class EventWrapper<TEventArgs> {
private event EventHandler<TEventArgs> Event;
private readonly HashSet<EventHandler<TEventArgs>> _subscribeOnces;
internal EventWrapper() {
_subscribeOnces = new HashSet<EventHandler<TEventArgs>>();
internal void Subscribe(EventHandler<TEventArgs> eventHandler) {
Console.WriteLine("Subscribing a delegate for a all invocations");
internal void SubscribeOnce(EventHandler<TEventArgs> eventHandler) {
Console.WriteLine("Subscribing a delegate for a single invocation");
_subscribeOnces.Add(eventHandler);
internal void Unsubscribe(EventHandler<TEventArgs> eventHandler) {
Console.WriteLine("Unsubscribing a delegate");
Console.WriteLine($"Delegates remaining {(Event == null ? 0 : Event.GetInvocationList().Length)}");
internal void UnsubscribeAll() {
foreach (EventHandler<TEventArgs> eventHandler in Event?.GetInvocationList()) {
internal void Invoke(Object sender, TEventArgs e) {
Console.WriteLine($"Invoking Event with {(Event == null ? 0 : Event.GetInvocationList().Length)} delegates");
Event?.Invoke(sender, e);
if(_subscribeOnces.Count > 0) {
foreach (EventHandler<TEventArgs> eventHandler in _subscribeOnces) {
Console.WriteLine($"Delegates remaining {(Event == null ? 0 : Event.GetInvocationList().Length)}");