Открыть список
Как стать автором
Обновить

Комментарии 29

Думаю было б неплохо перенести в блог про .NET
Сейчас попрошусь к ним :)
я пишу на .net, но мне в голову не приходит то, где я могу использовать эти техники
можете рассказать область применения или может быть примеры какие привести, для этого даже отдельную статью можно было бы сделать
Могу отдать тему на дальнейшую разработку :)
А область применения этой техники такая же, как и у рефлексии, в общем-то…

Например, задачка валидации состояния объектов на основе информации из какого-то файла конфигурации или даже DSL. Или самый «подножный» пример — это разработка своего супер-универсального DAL, чтобы одним методом проинициализировать любой тип данными из БД…
Ждем подробных постов :)
Да, так и есть. Писал когда-то свой класс, который мапится на таблицы в соответствии с аттрибутами свойств. Класс принимал в качестве параметра конструктора DataReader и из него инициализировался. Было бы полезно там оптимизировать, да только уже не поддерживаю этот проект :)

А как бы это сравнить с Reflection? намного ли быстрее работает, если суммарно взять результат по вашей коллекции из 20 элементов. Только тут, мне кажется, нужно будет графики составить некоторые, так как при маленьком объеме кол-ве данных будет быстрее рефлексия, а при большем кол-ве — ваш вариант. Хотя… Говорю навскидку, могу сильно ошибаться, время уже позднее ) Просто 23ms для получения _одного_ свойства из _одного_ объекта (как при первом вызове) — это достаточно медленно.
Здесь хорошая статья о том, как там дела обстоят со скоростями в Rеflection и различных способах оптимизации
Спасибо, ещё по ссылке в топике почитал. Только там используются возможности фреймворков более ранних версий (результатов с LINQ и вашего метода там нет)
Навскидку.

Такой код:

foreach (var entity in entities)
{
   var stopWatch = new Stopwatch();
   stopWatch.Start();

   var pi = typeof(Class1).GetProperty(«Property1», BindingFlags.Instance | BindingFlags.Public);
   var val = pi.GetValue(entity, null);

   stopWatch.Stop();
   Console.WriteLine(«{0}\t{1}», val, stopWatch.Elapsed);
}/* This source code was highlighted with Source Code Highlighter.*/


Показывает такой результат:



Что дает повод крепко пофлудить :)
Да, ещё и какой. Но не будем. :)

Я считаю, что каждый сам посчитать может. Ваш метод будет эффективен только при ОЧЕНЬ большом кол-ве записей. Иначе время, потраченное на первоначальную компиляцию не оправдает себя. Я это как-то так вижу.
Вот убей не пойму зачем сразу оптимизировать. Возможно, и не тормозит ничего. Контекст решает. Тема безусловно хорошая, автору плюс. Конечно, запомню, возможно, буду применять.
А вот про разбор Expression Tree было бы намного интереснее побеседовать. Уж больно популярны стали «Fluent» фреймворки. Может автор возьмется «разобрать» тему?;)
Безусловно, преждевременная оптимизация — зло. Но зато если она «навалилась» — для этого и написан этот пост :)
А про разбор expression trees придется дождаться подходящей проблемы в текущем проекте :)
Да, и ещё обратил внимание, что в тесте используется DateTime.Now.Millisecond — start!!!
Как-то, нули ничего не говорят о порядках ускорения. Может все-таки StopWatch использовать? Привыкли уже к нему вроде.
Специально для вас :)

Ну, почему только для меня?:) Я не жадный, пусть все смотрят. Но чистота эксперимента… и все такое.
Да, совет дельный :)
Вы знаете, после этого открываешь руби и видишь будущее С# и прошлое Lisp & SmallTalk :-)
Есть такая тенденция… Всякая функциональщина и динамика активно приходят в мейнстрим.

Но если и сравнивать это с каким-то языком, то скорее с Nemerle, который все эти штуки уже давно именно в .NET превнес.
Ну а кто это принес в сам Nemerle? :) Уж синтаксические деревья, Expression Trees и их генерация — это чистой воды lisp, который был придуман лет 50 назад. А после него это было реализованно мо многих других языках, как чисто в функциональных, так и в объектных. Что касается c#, то пока мы может посмотреть на примере, как __«что-то подобное»__ можно сделать на этом языке прибигая вот к таким методам. Ну а вообще ты прав, динамика активно приходит в мейнстримы.
Ну дык о роли LISP и SmalTalk никто и не спорит :) Nemerle был приведен, как более близкий для .NET язык, чем Ruby :)

А насчет C# — да, при всех своих новых достоинствах он остается слишком уж объектно-ориентированым…
>>Nemerle был приведен, как более близкий для .NET язык, чем Ruby :)

Дык я не говорил о наиболее технологической «близости», а скорее об глобально-идейной… наверное правильно было бы указать и другие языки, но что делать если в текущий момент я изучаю Руби? :)
Говорю сразу — я ничего против Ruby не имею :)
А какая разница, кто что куда привнёс?
Всё уже украдено до нас © (Ы)
Большая разница, так как знание корней и причин появление вещей не только полезно, но еще и интересно. Ну это к теме разговара не относится.
В этом решении есть проблемы. Работа такого геттера зависит от типа Property у класса. Например, для свойства с типом Double такое дерево вообще не компилируется. Выскакивает исключение об невозможности делегирования типа Double к типу Object
Коллега )
Тоже нашел по поиску эту статью (ей уже почти полтора года) и тоже споткнулся о значимый тип!
Вы, случаем, не нашли как обойти эту проблему?
Всё, понял, просто тема новая). Надо поменять сигнатуру функции на нужную, в вашем случае: Func<object, double>
Да, Func<object, double> в данной ситуации помогает, но теряется универсальность.
Есть решение: использовать обобщения (Generics) — но это опять-таки не всегда даст нужный результат.

А статья хоть и довольно не свежая, но содержит вполне актуальные данные. Это поистине приятное нововведение в C# 3.
Если в контексте Вашей программы можно использовать Func<object, double>, т.е. нет полной универсальности, то можно и так.
Если же хотите возвращать и значимые типы в качестве результата, то можно дерево немного дополнить
(t as Class).Property следующим образом: ((t as Class).Property as object)
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.