2009-03-01 6 views
22

Méthodes d'extension pour les indexeurs, seraient-ils bons? Je jouais avec un code qui réhydrate les POCO.Méthodes d'extension pour les indexeurs, seraient-ils bons?

Le code parcourt les lignes renvoyées à partir d'un SqlDataReader et utilise la réflexion pour affecter des propriétés aux valeurs de colonne. Au bas de ma pile d'appels, j'ai eu un code une ligne comme ceci: -

poco.Set("Surname", "Smith"); // uses extension method ... 

La méthode Set a été écrite comme une méthode d'extension.

Ce serait génial d'avoir pu écrire du code comme celui-ci

poco["Surname"] = "Smith"; // extension methods for indexers ? 

-à-dire que je voulais écrire une méthode d'extension pour indexeur

Y at-il une bonne raison pour laquelle .Net n'a pas les méthodes d'extension pour les indexeurs? Est-ce que d'autres personnes ont d'autres bonnes utilisations pour les indexeurs de méthode d'extension?

en aparté ... Si nous pouvions écrire des méthodes d'extension pour indexeurs alors nous pourrions écrire du code comme ça ...

var poco = PocoFactory(); 
    poco.Surname = “Smith”; // is this JavaScript ... 
    poco[Surname] = “Smith” ; // … or is this c# or both 

Quelques extraits de mon code

///////////////////////////////////////////// 
// Client calling code 
IDab dab = DabFactory.Create("Northwind"); 
string sql = @"select * from Customers "; 
var persons = dab.ExecuteReader<NorthwindCustomer>(sql); 
if (dab != null{ 
    Assert.That(persons[0].CustomerID , Is.EqualTo("ALFKI"));} 
///////////////////////////////////////////// 
List<T> IDab.ExecuteReader<T>(string commandText) 
{ 
    List<T> pocos = new List<T>(); 
    // setup connection 
    SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection); 
    while (reader.Read()) 
    { 
      Dictionary<string, int> colMappings = null ; 
      if (colMappings == null){ 
       colMappings = reader.GetSqlDataReaderColumnMappings();} 
      T poco = new T(); 
      poco.DbToMem<T>(reader, colMappings); 
      pocos.Add(poco); 
     } 
    } 
    // connection cleanup ... 
    return pocos ; 
} 

// the set extension method signature 
public static void Set<T>(this T thisClientObject, string thisPropertyName, object newValue) where T : class 

Répondre

11

indexeurs partagent beaucoup de communité avec les propriétés (sous le capot, un indexeur est une propriété avec un index), et les propriétés d'extension n'existent pas. D'accord, il y aurait des scénarios où ils sont pratiques.

Re le scénario présenté - à certains égards, c'est un peu comme dynamic. Bien sûr, si vous déclarez une interface a un indexeur de chaîne, alors votre lecteur-code pourrait l'utiliser directement - mais ce serait un travail inutile pour implémenter cette interface à plusieurs reprises!

Ré la méthode d'extension; cela utilise-t-il une réflexion régulière? Vous pourriez vouloir regarder des astuces comme HyperDescriptor, ce qui pourrait économiser beaucoup de temps CPU si vous faites beaucoup de cela. L'usage typique serait alors:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); 
while (reader.Read()) 
{ 
    T poco = new T(); 
    // abbreviated... 
    (per prop) 
     props[propName].SetValue(poco, cellValue); 
} 

Vous pouvez optimiser encore plus loin en regardant les colonnes renvoyées première (une fois par grille, et non par ligne), et que l'accès aux colonnes adaptées ...

Ou bien, regarder les outils ORM; Expression peut également être utilisé pour lire des données (j'en ai un exemple complet quelque part sur usenet, pour DbLinq)

+0

merci, je vais jeter un oeil. – judek

-1

Pour réhydrater les Pocos, je vous recommande de jeter un coup d'œil au paquet AutoMapper Nuget. Il est très simple et réduit considérablement la quantité de code.

Questions connexes