Delegates (in short) are variable types that pass around functions instead of values or objects. A delegate is defined by a signature (the unique combination of parameters and return type by which a function is recognized); any function with the same signature can be assigned to a delegate.

// delegate type
public delegate double Operation(double a, double b);
// delegate type variable
Operation myOperation;

// a valid function
public double Sum(double a, double b)
{
  return a + b;
}
// another valid function
public double Multiplication(double a, double b)
{
  return a * b;
}
// any other function that takes 2 doubles and returns one double is valid for the myOperation delegate variable

// assign the function to the delegate variable
myOperation = Sum;
// call the delegate (in another point of the code)
double result = myOperation (a, b);

The advantage of a delegate is in writing code for multiple scenarios with the same syntax, in this case empowering the user with the possibility to write bespoke methods and plug them in the standard Assembler core for the menial operations (clash check, topology management, etc.).

for more info, see: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/