2009-03-01 14 views
22

Métodos de extensión para indexadores, ¿serían buenos?Métodos de extensión para indexadores, ¿serían buenos?

Estaba jugando con un código que rehidrata POCO.

El código itera alrededor de las filas devueltas desde un SqlDataReader y utiliza la reflexión para asignar propiedades a partir de valores de columna. Bajé mi pila de llamadas y tuve un código de una línea como esta: -

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

El método Set se escribió como un método de extensión.

Sería muy bueno para haber sido capaz de escribir código como este

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

es decir que quería escribir un método de extensión para el indexador

¿Hay una buena razón por la cual .Net no tiene métodos de extensión para los indexadores? ¿Las otras personas tienen otros buenos usos para los indexadores de método de extensión?

como un aparte ... Si pudiéramos escribir métodos de extensión para los indexadores entonces podríamos escribir código como este ...

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

Algunos fragmentos de mi código

///////////////////////////////////////////// 
// 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 

Respuesta

11

indexadores comparten muchos de las características comunes con las propiedades (debajo del capó, un indexador es una propiedad con un índice), y las propiedades de extensión no existen. De acuerdo, habría escenarios en los que son útiles.

En el escenario presentado, de alguna manera, es bastante similar a dynamic. Por supuesto, si declara una interfaz que tiene un indexador de cadenas, entonces su código lector podría usarlo directamente, pero sería un lote de trabajo innecesario para implementar esta interfaz repetidamente.

Re el método de extensión; ¿Utiliza esto una reflexión regular? Es posible que desee ver trucos como HyperDescriptor, lo que puede ahorrar mucho tiempo de CPU si está haciendo mucho de esto. El uso típico sería entonces:

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

puede optimizar aún más esta mirando las primeras columnas devueltas (una vez por la red, no por fila), y sólo el acceso a las columnas coincidentes ...

O, alternativamente, mira las herramientas ORM; Expression también se puede utilizar para realizar la lectura de datos (tengo un ejemplo completo de esto en algún lugar de usenet, para DbLinq)

+0

gracias interesantes, voy a echar un vistazo. – judek

-1

Para rehidratar Pocos, recomendaría echarle un vistazo al paquete AutoMapper Nuget. Hace que sea realmente simple y reduce en gran medida la cantidad de código.

Cuestiones relacionadas