2013-01-05 3 views
9

Я делаю компилятор с .NET-совместимым использованием Reflection.Emit. Проблема в том, что хотя TypeBuilder получен из Type, он не позволяет мне использовать все удобные методы, которые предоставляет Type.Type.GetMethod альтернатива для TypeBuilder

Вопросы, которые действительно волнуют меня являются:

  1. Есть ли способ, чтобы получить список методов, полей, свойств, конструкторов и т.д., определенных в TypeBuilder, или я действительно должен сделать TypeBuilderWrapper что отслеживает все эти сущности собой? Он должен хранить их где-то внутри, поэтому должен быть какой-то способ их извлечения?

  2. Метод GetMethod очень удобен, так как он может найти оптимальный метод подбора, учитывающий наследование и общую ковариацию. Должен ли я действительно переопределить его сам для TypeBuilderWrapper?

Та же проблема, вероятно, относится и к MethodBuilder, FieldBuilder и т.д., которые, я считаю, не реализовать методы подстановки из MethodInfo и FieldInfo соответственно.

+0

Возможно, это не тот ответ, который вы ищете. Но посмотрели ли вы в DLR (http://dlr.codeplex.com/)? – rpgmaker

+0

@ rpgmaker Не могли бы вы объяснить, как именно DLR поможет здесь? – svick

+1

Не можете ли вы вызвать 'CreateType()' перед попыткой использовать 'GetMethod()'? Кроме того, вы могли бы объяснить * почему * вам нужно разрешение перегрузки? При генерации кода вы обычно знаете, какой метод вы хотите вызвать. – svick

ответ

9

TypeBuilder, MethodBuilder, и т.д. Type, MethodInfo, но они не имеют все способности Type, MethodInfo, пока вы не вызовете TypeBuilder.CreateType(). Причина TypeBuilder взята из Type, она позволяет вам при строительстве классов A и B, вы можете ссылаться на них в обоих направлениях, не заканчивая их. Позвольте мне привести пример:

// sample.x 
class A { 
    void method1(B b) {} 
} 

class B { 
    void method2(A a) {} 
} 

Таким образом, # код C для создания класса A и B бы:

// ... 
// define classes 
TypeBuilder classA = moduleBuilder.DefineType("A"); 
TypeBuilder classB = moduleBuilder.DefineType("B"); 

// define class A's methods 
MethodBuilder method1 = classA.defineMethod("method1", MethodAttributes.Public); 
method1.SetParameters(classB); 
// ... build method body 

// define class B's methods 
MethodBuilder method2 = classB.defineMethod("method2", MethodAttributes.Public); 
method1.SetParameters(classA); 
// ... build method body 

// finish classes 
classA.CreateType(); 
classB.CreateType(); 
// this time you can use GetMethod but you can not modify classes any more. 

ответить на ваши вопросы, нет способа получить список методов, свойств и т.д. в TypeBuilder, пока не позвоните по номеру CreateType. Но вы должны помнить эти методы, свойства создаются вашим кодом, поэтому вы должны знать их все. Если вы хотите создать какой-то класс TypeBuilderWrapper, это ваш выбор. Но с моей точки зрения, вы должны сделать что-то вроде:

  • Напишите свои собственные модели (XClass, XMethod, XParam и т.д.) для вас X языка.
  • Поверните свой XParser, чтобы проанализировать файлы X в объектах языковой модели.
  • Проведите некоторый анализ созданных моделей для создания связей между вашими моделями. Например: в sample.x выше, в B.method2, параметр A a должен иметь ссылку на модель class A.
  • с использованием Reflection.Emit для создания целевой сборки. Помните, что порядок: определить классы, определить методы классов, определить тело методов методов и т. Д. Затем позвоните CreateType, чтобы закончить все. Заказ может быть изменен, зависит от вашего языка.

Все это моя идея, этот код может не работать.Когда я создал свой простой глупый язык, я создал нечто подобное. Надеюсь, я могу тебе помочь.

+0

Да, из-за меня я был сведен к выполнению этих классов-оболочек вручную, и это было очень надоедливо. Еще более разочаровывает тот факт, что 'TypeBuilder' запечатан, и вы не можете создать простой производный класс без нарушения интерфейса. Спасибо за ваш комментарий. – Impworks

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