2009-03-01 10 views
22

Erweiterungsmethoden für Indexer, wären sie gut?Erweiterungsmethoden für Indexer, wären sie gut?

Ich spielte mit etwas Code, der POCO's hydratisiert.

Der Code iteriert Zeilen, die von einem SqlDataReader zurückgegeben werden, und verwendet Reflektion, um Eigenschaften aus Spaltenwerten zuzuweisen. In meinem Callstack hatte ich einen Code wie folgt:

Die Set-Methode wurde als eine Erweiterungsmethode geschrieben.

Es wäre toll, in der Lage gewesen, Code zu schreiben, wie diese

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

dh ich eine Erweiterungsmethode für Indexer

Gibt es guten Grund schreiben wollte, warum .Net nicht Erweiterungsmethoden hat für Indexer? Haben andere Personen andere nützliche Anwendungen für Indexer für Erweiterungsmethoden?

als beiseite ... Wenn wir Erweiterungsmethoden für Indexer schreiben könnte dann könnten wir Code wie diesen schreiben ...

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

Einige Auszüge aus meinem 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 

Antwort

11

Indexer teilen viel der Gemeinsamkeit mit Eigenschaften (unter der Haube, ein Indexer ist eine Eigenschaft mit einem Index), und Erweiterung Eigenschaften nicht vorhanden. Einverstanden, es würde Szenarien geben, wo sie nützlich sind.

Re das Szenario präsentiert - in gewisser Hinsicht ist dies wie dynamic. Natürlich, wenn Sie eine Schnittstelle, die hat einen String-Indexer, dann könnte Ihr Leser-Code könnte es direkt verwenden - aber es wäre ein Los der unnötigen Arbeit, um diese Schnittstelle wiederholt zu implementieren!

Re die Erweiterungsmethode; verwendet das regelmäßige Reflexion? Vielleicht möchten Sie sich Tricks wie HyperDescriptor ansehen, die viel CPU-Zeit sparen, wenn Sie viel davon machen. Typische Anwendungen wären dann:

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

du weitere erste durch einen Blick auf den zurückgegebenen Spalten optimieren können (einmal pro Raster, nicht pro Zeile), und nur angepasst Spalte Zugriff auf ...

Oder alternativ, Schauen Sie sich ORM-Tools an. Expression kann auch verwendet werden, um Daten zu lesen (ich habe ein komplettes Beispiel irgendwo auf Usenet, für DbLinq)

+0

interessanten Dank, ich werde es mir ansehen. – judek

-1

Zum Rehydrierung Pocos, würde ich empfehlen, einen Blick auf das AutoMapper Nuget-Paket. Es macht es wirklich einfach und reduziert die Menge an Code erheblich.

Verwandte Themen