title: Convert delegate to Action<T> (Action<T1,T2>)
body: <p>I have a DB class that makes all DB calls like below:</p>
  
  <pre><code>public delegate void Part1_Callback(string message);
  public delegate void Part2_Callback(DataTable dt);
  public delegate void Part3_Callback(DataTable dt, int x, int y);
  public delegate void ErrorHandler(string message);
  
  public class CommandAndCallback&lt;TCallback&gt;
  {
      public SqlCommand Sql { get; set; }
      public TCallback Callback { get; set; }
      public ErrorHandler Error { get; set; }
  }
  
  class DB : SingletonBase&lt;DB&gt;
  {
      public static readonly string SqlConnectionString  = @"Data Source=MyDB;Initial Catalog=Stats;Integrated Security=True;Asynchronous Processing=true;";
  
      private DB()
      {
      }
  
      public void Part2(Part2_Callback callback, ErrorHandler error)
      {
          SqlConnection conn = new SqlConnection(SqlConnectionString);
          SqlCommand cmd = conn.CreateCommand();
          cmd.CommandType = CommandType.StoredProcedure;
          cmd.CommandText = "Part2";
  
          try
          {
              conn.Open();
          }
          catch (Exception ex)
          {
              error(ex.ToString());
              return;
          }
  
          CommandAndCallback&lt;Part2_Callback&gt; ar = new CommandAndCallback&lt;Part2_Callback&gt;() { Callback = callback, Error = error, Sql = cmd };
          IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(Part2_Handler), ar, CommandBehavior.CloseConnection);
      }
  
      private void Part2_Handler(IAsyncResult result)
      {
          DataTable dt = new DataTable();
          CommandAndCallback&lt;Part2_Callback&gt; ar = (CommandAndCallback&lt;Part2_Callback&gt;)result.AsyncState;
          SqlDataReader dr;
  
          if (result.IsCompleted)
          {
              dr = ar.Sql.EndExecuteReader(result);
          }
          else
              dr = null;
  
          dt.Load(dr);
          dr.Close();
          dt.Columns[3].ReadOnly = false;
          ar.Callback(dt);
      }
  }
  </code></pre>
  
  <p>And in my main class I'm using it like so:</p>
  
  <pre><code>    private void Form1_Enter(object sender, EventArgs e)
      {
          showStatus("Loading");
          DB.Instance.Part2(Part2_OK, ErrorHandler);
      }
      private void ErrorHandler(string msg)
      {
          hideStatus();
          viewStack1.InvokeIfRequired(c =&gt; { c.moveToFirst(); });
          //MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
  
      private void Part2_OK(DataTable dt)
      {
          dataGridView1.InvokeIfRequired(c =&gt;
          {
              c.DataSource = dt;
          });
      }
  </code></pre>
  
  <p>Right now I have 3 methods in my DB class that return 3 different sets of data, for every type I must declare delegate.<br>
  If in future I'll add more methods then I'll have to add more delegates.</p>
  
  <p>Can I remove usage of delegates? I would like to simplify build of my class so that it will be easy to add new methods.</p>
  
  <p>What I need is to be able to call my DB Class like so:</p>
  
  <pre><code>DB.Instance.PartX(PartX_OK, ErrorHandler);
  </code></pre>
  
  <p>PartX is declared as shown</p>
  
  <pre><code>private void PartX_OK(DataTable dt, int x, int y, ...)
  {
  //logic here
  }
  </code></pre>
  
  <p>Can <code>Action&lt;T&gt;</code> be used to to that, so I can call my handlers with multiple parameters? If yes then how?</p>