Skip to content

Instantly share code, notes, and snippets.

@NickStrupat
Last active November 4, 2016 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NickStrupat/cadf7e3ea5ae1b8165e17629df2dc64a to your computer and use it in GitHub Desktop.
Save NickStrupat/cadf7e3ea5ae1b8165e17629df2dc64a to your computer and use it in GitHub Desktop.
Event delegate contravariance
private ImmutableArray<THandler> handlers = ImmutableArray<THandler>.Empty;
internal static void Add<THandler>(ref ImmutableArray<Action<THandler>> handlers, Action<THandler> handler) {
if (handler == null)
return;
ImmutableArray<Action<THandler>> initial, computed;
do {
initial = InterlockedGet(ref handlers);
computed = initial.Add(handler);
}
while (initial != ImmutableInterlocked.InterlockedCompareExchange(ref handlers, computed, initial));
}
internal static void Remove<THandler>(ref ImmutableArray<Action<THandler>> handlers, Action<THandler> handler) {
if (handler == null)
return;
ImmutableArray<Action<THandler>> initial, computed;
do {
initial = InterlockedGet(ref handlers);
computed = RemoveLast(initial, handler);
}
while (initial != ImmutableInterlocked.InterlockedCompareExchange(ref handlers, computed, initial));
}
private static void Raise<THandler>(ref ImmutableArray<Action<THandler>> handlers, THandler entry) {
var latestHandlers = InterlockedGet(ref handlers);
for (var i = 0; i < latestHandlers.Length; i++)
latestHandlers[i].Invoke(entry);
}
private static ImmutableArray<Action<THandler>> InterlockedGet<THandler>(ref ImmutableArray<Action<THandler>> handlers) {
return ImmutableInterlocked.InterlockedCompareExchange(ref handlers, ImmutableArray<Action<THandler>>.Empty, ImmutableArray<Action<THandler>>.Empty);
}
private static ImmutableArray<TDelegate> RemoveLast(ImmutableArray<TDelegate> source, TDelegate value) {
var list = source;
var index = list.LastIndexOf(value);
if (index >= 0)
return list.RemoveAt(index);
return list;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment