Подтвердить что ты не робот

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

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

Я играл с некоторым кодом, который повторно увлажняет 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
4b9b3361

Ответ 1

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

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

Повторить метод расширения; это использует регулярное отражение? Возможно, вы захотите посмотреть на трюки, такие как 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)

Ответ 2

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