2009-03-01 8 views
22

Metodi di estensione per gli indicizzatori, sarebbero buoni?Metodi di estensione per gli indicizzatori, sarebbero buoni?

Stavo giocando con un codice che reidrata i POCO.

Il codice itera attorno a righe restituite da un oggetto SqlDataReader e utilizza reflection per assegnare proprietà dai valori di colonna. Giù il mio stack di chiamate ho avuto un codice di una linea come questa: -

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

il metodo di cui è stato scritto come un metodo di estensione.

Sarebbe bello di essere stato in grado di scrivere codice come questo

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

cioè volevo scrivere un metodo di estensione per indicizzatore

ci sono buoni motivi per cui .NET non hanno metodi di estensione per gli indicizzatori? Altre persone hanno altri buoni usi per gli indicizzatori del metodo di estensione?

come divagazione ... Se potessimo scrivere metodi di estensione per gli indicizzatori allora potremmo scrivere codice come questo ...

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

alcuni frammenti dal mio codice

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

risposta

11

indicizzatori condividono un sacco di comunanza con le proprietà (sotto il cofano, un indicizzatore è una proprietà con un indice) e le proprietà di estensione non esistono. D'accordo, ci sarebbero degli scenari in cui sono a portata di mano.

Re lo scenario presentato - in qualche modo, è abbastanza simile a dynamic. Naturalmente, se dichiari un'interfaccia che ha un indice di stringa, il tuo codice di lettura potrebbe usarlo direttamente, ma sarebbe un lotto di lavoro non necessario per implementare questa interfaccia ripetutamente!

Re il metodo di estensione; questo usa una riflessione regolare? Potresti voler prendere in considerazione trucchi come HyperDescriptor, che potrebbe far risparmiare molto tempo alla CPU se stai facendo molto di questo. utilizzo tipico sarebbe allora:

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

È possibile ottimizzare ulteriormente questo guardando le colonne restituite prime (una volta alla griglia, non per riga), e solo l'accesso a colonne abbinate ...

Oppure, in alternativa, guarda gli strumenti ORM; Expression può anche essere usato per fare la lettura dei dati (Ho un esempio completo di questo da qualche parte per il download diretto, per DbLinq)

+0

grazie interessanti, darò un'occhiata. – judek

-1

Per ri-idratazione Pocos, vi consiglio di dare un'occhiata al pacchetto automapper Nuget. Rende è davvero semplice e riduce notevolmente la quantità di codice.

Problemi correlati