title: Use of Generic Delegates
body: <p>We know that "Action, Func and Predicate are pre-defined Generic delegates. So as delegate they can point to functions with specified signature."</p>
  
  <p>I have following data-access scenario in which <code>Func&lt;T,R&gt;</code> helps in <code>avoiding a foreach loop</code> in the calling method. The approach 2 doesn’t have looping. Here <code>Func&lt;T,R&gt;</code> helped to avoid loop.</p>
  
  <p>What are the other scenarios for generic delegates in which it can save lots of lines of code?</p>
  
  <p><strong>REFERENCES</strong></p>
  
  <ol>
  <li><a href="http://www.albahari.com/nutshell/predicatebuilder.aspx" rel="nofollow noreferrer">Dynamically Composing Expression Predicates</a></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx" rel="nofollow noreferrer">Advanced C#</a></li>
  <li><a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2011/11/24/c.net-little-wonders-the-predicate-comparison-and-converter-generic-delegates.aspx" rel="nofollow noreferrer">C#/.NET Little Wonders: The Predicate, Comparison, and Converter Generic Delegates</a></li>
  <li><a href="https://stackoverflow.com/questions/4317479/func-vs-action-vs-predicate">Func vs. Action vs. Predicate</a></li>
  <li><a href="https://stackoverflow.com/questions/3624731/what-is-func-how-and-when-is-it-used">What is Func, how and when is it used</a></li>
  <li><a href="https://stackoverflow.com/questions/12578965/how-can-i-pass-in-a-func-with-a-generic-type-parameter">How can I pass in a func with a generic type parameter?</a></li>
  </ol>
  
  <p>CODE</p>
  
  <p><strong>Approach 1</strong></p>
  
  <pre><code>public class MyCommonDAL
  {
  
      public static IEnumerable&lt;IDataRecord&gt; ExecuteQueryWithTextCommandType(string commandText, List&lt;SqlParameter&gt; commandParameters)
      {
          using (SqlConnection connection = new SqlConnection(connectionString))
          {
              using (SqlCommand command = new SqlCommand())
              {
                  command.Connection = connection;
                  command.CommandType = CommandType.Text;
                  command.CommandText = commandText;
                  command.CommandTimeout = 0;
                  command.Parameters.AddRange(commandParameters.ToArray());
  
                  connection.Open();
                  using (var rdr = command.ExecuteReader())
                  {
                      while (rdr.Read())
                      {
                          yield return rdr;
                      }
                      rdr.Close();
                  }
              }
          }
      }
  
  }
  
  
  public class MyLogDAL
  {
      public List&lt;LogSeverityType&gt; GetLogSeveritiesFirstApproach(LogSeverityType logSeverityType)
      {
  
  
          List&lt;SqlParameter&gt; commandParameters = new List&lt;SqlParameter&gt;()
                                                  {
                                                      new SqlParameter {ParameterName = "@CreatedDateTime", 
                                                                        Value = logSeverityType.CreatedDateTime, 
                                                                        SqlDbType = SqlDbType.DateTime}
                                                  };
  
  
          string commandText = @"SELECT * FROM dbo.LogSeverityType WHERE CreatedDateTime &gt; @CreatedDateTime";
          var results = MyCommonDAL.ExecuteQueryWithTextCommandType(commandText, commandParameters);
  
          List&lt;LogSeverityType&gt; logSeverities = new List&lt;LogSeverityType&gt;();
  
   //LOOP
          foreach (IDataRecord rec in results)
          {
              LogSeverityType objLogSeverityType = LogSeverityType.LogSeverityTypeFactory(rec);
              logSeverities.Add(objLogSeverityType);
          }
  
  
          return logSeverities;
      }
  
  
  
  }
  </code></pre>
  
  <p><strong>Approach 2</strong></p>
  
  <pre><code>    public class MyCommonDAL
      {
  
          public static IEnumerable&lt;T&gt; ExecuteQueryGenericApproach&lt;T&gt;(string commandText, List&lt;SqlParameter&gt; commandParameters, Func&lt;IDataRecord, T&gt; factoryMethod)
          {
  
              //Action, Func and Predicate are pre-defined Generic delegates.
              //So as delegate they can point to functions with specified signature.
  
              using (SqlConnection connection = new SqlConnection(connectionString))
              {
                  using (SqlCommand command = new SqlCommand())
                  {
                      command.Connection = connection;
                      command.CommandType = CommandType.Text;
                      command.CommandText = commandText;
                      command.CommandTimeout = 0;
                      command.Parameters.AddRange(commandParameters.ToArray());
  
                      connection.Open();
                      using (var rdr = command.ExecuteReader())
                      {
                          while (rdr.Read())
                          {
                              yield return factoryMethod(rdr);
                          }
                          rdr.Close();
                      }
                  }
              }
          }
  
  
      }
  
  
      public class MyLogDAL
      {
  
          public List&lt;LogSeverityType&gt; GetLogSeveritiesSecondApproach(LogSeverityType logSeverityType)
          {
  
  
              List&lt;SqlParameter&gt; commandParameters = new List&lt;SqlParameter&gt;()
                                                      {
                                                          new SqlParameter {ParameterName = "@CreatedDateTime", 
                                                                            Value = logSeverityType.CreatedDateTime, 
                                                                            SqlDbType = SqlDbType.DateTime}
                                                      };
  
  
              string commandText = @"SELECT * FROM dbo.LogSeverityType WHERE CreatedDateTime &gt; @CreatedDateTime";
              //var results = MyCommonDAL.ExecuteQueryWithTextCommandType(commandText, commandParameters);
  
              IEnumerable&lt;LogSeverityType&gt; logSeverities = MyCommonDAL.ExecuteQueryGenericApproach&lt;LogSeverityType&gt;(commandText, commandParameters, LogSeverityType.LogSeverityTypeFactory);
  
              //foreach (IDataRecord rec in results)
              //{
              //    LogSeverityType objLogSeverityType = LogSeverityType.LogSeverityTypeFactory(rec);
              //    logSeverities.Add(objLogSeverityType);
              //}
  
  
              return logSeverities.ToList();
          }
  
  
      }
  </code></pre>
  
  <p><strong>Other Code Required</strong></p>
  
  <pre><code>    public class LogSeverityType
      {
          public int LogSeverityTypeID { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }
          public DateTime CreatedDateTime { get; set; }
  
          public static LogSeverityType LogSeverityTypeFactory(IDataRecord record)
          {
              return new LogSeverityType
              {
                  LogSeverityTypeID = (int)record[0],
                  Name = (string) record[1],
                  Description = (string)record[2],
                  CreatedDateTime = (DateTime) record[3]
              };
          }
      }
  
          static void Main(string[] args)
          {
              MyLogDAL logDAL = new MyLogDAL();
              LogSeverityType logSeverityType = new LogSeverityType();
              logSeverityType.CreatedDateTime = Convert.ToDateTime("1/1/2000");
  
              List&lt;LogSeverityType&gt; logSeverities = logDAL.GetLogSeveritiesSecondApproach(logSeverityType);
          }
  </code></pre>