2009-03-01 7 views
22

Методы расширения индексировщиков, будут ли они хорошими?Методы расширения индексировщиков, будут ли они хорошими?

Я играл с некоторым кодом, который повторно увлажняет POCO.

Код повторяется вокруг строк, возвращаемых из SqlDataReader, и использует отражение для назначения свойств из значений столбцов. В моем стеке вызовов у меня был код такой строки: -

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

Метод Set был записан как метод расширения.

Было бы здорово, чтобы быть в состоянии написать код, как этот

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

то я хотел написать метод расширения для индексатор

Есть хорошие причины, почему .Net не имеет методы расширения для индексаторов? У других людей есть другие хорошие применения для индексаторов метода расширения?

как в сторону ... Если бы мы могли написать методы расширения для индексаторов, то мы могли бы написать код, как это ...

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

Некоторые фрагменты из моего кода

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

ответ

11

Индексаторы имеют много общности со свойствами (под капотом индекс равен свойство с индексом), а свойства расширения не существуют. Согласитесь, там будут сценарии, где они удобны.

Re: представленный сценарий - в некотором роде, это совсем как dynamic. Конечно, если вы объявите интерфейс, что имеет указатель на строку, то ваш код-читатель может использовать его напрямую, но это будет лот ненужной работы для повторного использования этого интерфейса!

Re метод расширения; это использует регулярное отражение? Возможно, вы захотите посмотреть на трюки, такие как HyperDescriptor, что может сэкономить много процессорного времени, если вы много чего делаете. Типичное использование будет затем:

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

Вы можете оптимизировать это дальше, посмотрев на возвращенных столбцах первых (один раз в сетку, а не для каждой строки), а только доступ к совпавшим столбцам ...

Или же, взгляните на инструменты ORM; Expression также может использоваться для чтения данных (у меня есть полный пример этого где-то на usenet, для DbLinq)

+0

интересное спасибо, я посмотрю. – judek

-1

Для повторного увлажнения Pocos я бы рекомендовал взглянуть на пакет AutoMapper Nuget. Это действительно просто и значительно уменьшает количество кода.