2010-04-27 3 views
3

Итак, я пытаюсь исследовать это все утро и не повезло. Я пытаюсь найти способ динамического создания метода/delegate/lambda, который возвращает новый экземпляр определенного класса (неизвестный до выполнения), который наследуется от определенного базового класса.Создание динамического метода

Я могу гарантировать следующее о неизвестном/динамическом классе

  1. Он всегда будет наследовать от одного известного класса (Row)
  2. Он будет иметь по крайней мере 2 конструкторов (один принимающий длинные и один принимающий IDataRecord)

Я планирую doign следующее:

  1. Поиск всех гр дивчины, которые имеют определенный атрибут на них
  2. Создания делегат/метод/лямбды/все, что создает новый экземпляр класса
  3. Сохранения делегата/независимо наряду с некоторыми свойствами в STRUCT/классе
  4. ВКЛАДЫША struct в hashtable
  5. При необходимости вытащите информацию из хеш-таблицы и вызовите делегат/все, чтобы получить новый экземпляр класса и вернув его/добавив его в список/etc.

Мне нужна помощь только с № 2 выше !!! Я не знаю, с чего начать. Мне действительно нужен какой-то справочный материал, чтобы начать меня, или некоторые ключевые слова, которые нужно бросить в Google.

Это для компактного/простого в использовании ORM для нашего офиса здесь. Я понимаю, что это не так просто, но, работая, нужно сделать код невероятно простым.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация! И спасибо заранее! :)

ответ

4

Вы можете использовать LINQ выражения для построения лямбды (long p) => new XXX(p) as Row во время выполнения:

Type type = // ... 
ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(long) }); 

var p = Expression.Parameter(typeof(long), "p"); 
var expr = Expression.Lambda<Func<long, Row>>(
       Expression.TypeAs(
        Expression.New(ctor, p), 
        typeof(Row)), 
       p); 

Func<long, Row> rowCreator = expr.Compile(); 

Row row = rowCreator(10); 
+1

Никогда не видел хорошего использования выражений, но вы немного открыли мне глаза :) – Stormenet

+0

Мне нравится стиль, но он скомпилирован с реальным ИЛом и отличается от производительности как long long(); – Andrey

+0

@Andrey: 'expr.Compile()' компилирует выражение в real IL. Производительность такая же, как если бы выражение lambda было скомпилировано во время компиляции, так что это так хорошо, как можно получить :-) – dtb

3

что относительно Activator.CreateInstance?

образец:

string typeName = ...; 
Activator.CreateInstance(Type.GetType(typeName), params); 
+0

Я считаю, что перегрузка CreateInstance, которая позволяет указать аргументы конструктора. Это было бы вашим лучшим выбором. – Tejs

+0

Это будет работать нормально, если только он не должен делать это тысячи раз в секунду, и в этом случае скомпилированный делегат будет намного лучше. – Gabe

+0

Я ищу скомпилированный делегат: - \ Это будет запущено на веб-сайте, и я хотел бы, чтобы любые ухудшения производительности от отражения возникали один раз при загрузке, если это возможно. – TJMonk15

Смежные вопросы