C# System namespace defines several generic delegates to convert almost all possible method signatures.
 
delegate TResult Func  ();
delegate TResult Func  (T arg);
delegate TResult Func  (T1 arg1, T2 arg2);
... and so on, up to T16
delegate void Action ();
delegate void Action  (T arg);
delegate void Action  (T1 arg1, T2 arg2);
... and so on, up to T16
We can rewrite the printer delegate as follows.
 
using System;
class Test
{
 static void output(int[] intArray, Action p)
 {
 foreach (int i in intArray)
 {
 p(i);
 }
 }
 static void consolePrinterInt(int i)
 {
 Console.WriteLine(i);
 }
 static void Main()
 {
 Action p = consolePrinterInt;
 int[] intArray = new int[] { 1, 2, 3 };
 output(intArray, p);
 }
}
 
The output:
1
2
3