Skip to content

Instantly share code, notes, and snippets.

@BoolPurist
Last active July 1, 2022 13:07
Show Gist options
  • Save BoolPurist/f3db42034b44c1e86b87a5948ddd0970 to your computer and use it in GitHub Desktop.
Save BoolPurist/f3db42034b44c1e86b87a5948ddd0970 to your computer and use it in GitHub Desktop.
Delegate under the Hood.
internal static class Program
{
public delegate void DoSomething();
// Compiler created this class in background because of public delegate void DoSomething().
public class DoSomethingDelegate
{
private List<DoSomething>? _invocationList = new List<DoSomething>();
public DoSomethingDelegate(DoSomething function)
{
_invocationList.Add(function);
}
private DoSomethingDelegate()
{
_invocationList = null;
}
public void Invoke()
{
foreach (var function in _invocationList)
{
function();
}
}
public static implicit operator DoSomethingDelegate(DoSomething toConvert)
{
return new DoSomethingDelegate(toConvert);
}
public static DoSomethingDelegate? operator -(DoSomethingDelegate self, DoSomething other)
{
var newList = new List<DoSomething>();
var selfList = self._invocationList == null ? new List<DoSomething>() : self._invocationList;
newList.AddRange(selfList);
if (newList.Contains(other))
{
newList.Remove(other);
}
DoSomethingDelegate newDelegate = new DoSomethingDelegate();
newDelegate._invocationList = newList;
if (newDelegate._invocationList.Count == 0)
{
return null;
}
return newDelegate;
}
public static DoSomethingDelegate? operator +(DoSomethingDelegate self, DoSomething other)
{
var newList = new List<DoSomething>();
var selfList = self._invocationList == null ? new List<DoSomething>() : self._invocationList;
newList.AddRange(selfList);
newList.Add(other);
DoSomethingDelegate newDelegate = new DoSomethingDelegate();
newDelegate._invocationList = newList;
if (newDelegate._invocationList.Count == 0)
{
return null;
}
return newDelegate;
}
}
static void Main(string[] args)
{
// Made possible by public constructor. Behaves like delegate.
DoSomethingDelegate functionList1 = new DoSomethingDelegate(PrintHello);
DoSomething someDelegate1 = new DoSomething(PrintHello);
// Made possible by conversion implicit operator.
DoSomethingDelegate functionList2 = someDelegate1;
// Made possible with overloading operators of + and - for DoSomethingDelegate class
functionList1 += PrintHello;
functionList1 -= PrintHello;
functionList1 -= PrintHello;
functionList1.Invoke();
// Difference between DoSomethingDelegate and DoSomething
// Possible
DoSomething someDelegate2 = PrintHello;
// Not possible
// DoSomethingDelegate functionList2 = PrintHello;
}
private static void PrintHello()
{
Console.WriteLine("Hello");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment