2013-12-19 1 views
7

Wir wissen, dass "Action, Func und Predicate sind vordefinierte Generische Delegaten. So als Delegate können sie auf Funktionen mit der angegebenen Signatur zeigen."Verwendung von generischen Delegaten

Ich habe folgende Daten-Access-Szenario, in dem Func<T,R> in avoiding a foreach loop in der aufrufenden Methode hilft. Der Ansatz 2 hat keine Schleife. Hier half Func<T,R> Schleife zu vermeiden.

Was sind die anderen Szenarien für generische Delegaten, in denen es viele Zeilen Code speichern kann?

REFERENZEN

  1. Dynamically Composing Expression Predicates
  2. Advanced C#
  3. C#/.NET Little Wonders: The Predicate, Comparison, and Converter Generic Delegates
  4. Func vs. Action vs. Predicate
  5. What is Func, how and when is it used
  6. How can I pass in a func with a generic type parameter?

CODE

Ansatz 1

public class MyCommonDAL 
{ 

    public static IEnumerable<IDataRecord> ExecuteQueryWithTextCommandType(string commandText, List<SqlParameter> 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<LogSeverityType> GetLogSeveritiesFirstApproach(LogSeverityType logSeverityType) 
    { 


     List<SqlParameter> commandParameters = new List<SqlParameter>() 
               { 
                new SqlParameter {ParameterName = "@CreatedDateTime", 
                     Value = logSeverityType.CreatedDateTime, 
                     SqlDbType = SqlDbType.DateTime} 
               }; 


     string commandText = @"SELECT * FROM dbo.LogSeverityType WHERE CreatedDateTime > @CreatedDateTime"; 
     var results = MyCommonDAL.ExecuteQueryWithTextCommandType(commandText, commandParameters); 

     List<LogSeverityType> logSeverities = new List<LogSeverityType>(); 

//LOOP 
     foreach (IDataRecord rec in results) 
     { 
      LogSeverityType objLogSeverityType = LogSeverityType.LogSeverityTypeFactory(rec); 
      logSeverities.Add(objLogSeverityType); 
     } 


     return logSeverities; 
    } 



} 

Ansatz 2

public class MyCommonDAL 
    { 

     public static IEnumerable<T> ExecuteQueryGenericApproach<T>(string commandText, List<SqlParameter> commandParameters, Func<IDataRecord, T> 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<LogSeverityType> GetLogSeveritiesSecondApproach(LogSeverityType logSeverityType) 
     { 


      List<SqlParameter> commandParameters = new List<SqlParameter>() 
                { 
                 new SqlParameter {ParameterName = "@CreatedDateTime", 
                      Value = logSeverityType.CreatedDateTime, 
                      SqlDbType = SqlDbType.DateTime} 
                }; 


      string commandText = @"SELECT * FROM dbo.LogSeverityType WHERE CreatedDateTime > @CreatedDateTime"; 
      //var results = MyCommonDAL.ExecuteQueryWithTextCommandType(commandText, commandParameters); 

      IEnumerable<LogSeverityType> logSeverities = MyCommonDAL.ExecuteQueryGenericApproach<LogSeverityType>(commandText, commandParameters, LogSeverityType.LogSeverityTypeFactory); 

      //foreach (IDataRecord rec in results) 
      //{ 
      // LogSeverityType objLogSeverityType = LogSeverityType.LogSeverityTypeFactory(rec); 
      // logSeverities.Add(objLogSeverityType); 
      //} 


      return logSeverities.ToList(); 
     } 


    } 

Andere Code erforderlich

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<LogSeverityType> logSeverities = logDAL.GetLogSeveritiesSecondApproach(logSeverityType); 
     } 
+1

"Was sind die anderen wichtigsten 5 Anwendungsszenarien für generische Delegaten?" - Das ist doch subjektiv? – Nathan

+1

Sicher, keine Frage dazu - aber sollte wohl über http://programmers.stackexchange.com/ gehen? – Nathan

+1

@Nathan: Ich denke sogar [programmers.se] würde dies ablehnen. Es ist reine Meinung und nichts anderes. –

Antwort

1

Ich verwende generische Delegaten beim Analysieren/Finden von Knoten in XML/HTML-Dokumenten und beim Zuweisen der Werte zu Eigenschaften. Ich schrieb a blog post about it, die Refactoring des Codes zeigt, um in einem generischen Delegaten zu übergeben, und wie viel Code entfernt wurde.