2010-08-23 2 views
1

У меня были некоторые проблемы с выяснением хорошего названия, но, надеюсь, примеры кода в этом сообщении достаточно ясны.Деревья выражений: получение инструкций из метода MethodCallExpression

Возможно ли с помощью деревьев выражений (или какой-либо другой техники) пройти весь метод «стек вызовов»? По-разному: когда я получаю дерево выражений из Action-delegate, я хотел бы пересечься внутри операторов, которые происходят внутри делегата.

Я думаю, что лучше как можно скорее перейти к примерам ... У меня есть абстрактный класс под названием Command. Внутри Командования находится следующий метод:

protected void Run() 
{ 
    RunCommand (() => this.Execute()); 
} 

Выполнение - это абстрактный метод, реализуемый моими подклассами. Вот пример одного Execute-метода:

protected override void Execute() 
    { 
     var data = new RegistrationData {HomeTown = "town"}; 
     service.SendNewRegistration(data); 
    } 

В моей RunCommand-метод, который я хотел бы, чтобы мои руки на заявления внутри метода Execute-. Метод определяется следующим образом:

protected void RunCommand(Expression<Action> expression) 
{ 
    // Is it possible to find out that we're calling SendNewRegistration 
    // of a service-instance in our expression? 

    expression.Compile().Invoke(); 
} 

Перед вызовом Invoke, можно узнать, что происходит внутри суб-классы Execute-метод? Что объявлено, какие методы выполняются и какие параметры используются?

Я пытался продлить ExpressionVisitor, чтобы увидеть, что происходит, и сделал это, чтобы войти VisitMethodCall-расстрелы:

protected override Expression VisitMethodCall(MethodCallExpression m) 
    { 
     Debug.WriteLine(m.Method.Name); 
     return m; 
    } 

И выход был: Execute. Так что это не заставило меня далеко. Достаточно ли догадаться, какие утверждения содержатся в методе Execute?

+0

Могу ли я спросить, почему вы хотите это сделать? Может быть, есть и другие варианты ... –

+0

Все началось, когда я попытался упорядочить базовые классы модульных тестов. Те модульные тесты используются для тестирования контроллеров asp.net mvc 2, и поскольку мои модели используют аннотации данных, я должен принудительно выполнить проверку для моделей вручную. Я хотел полностью скрыть это от своих тестов, чтобы базовый класс справился с этим. Затем он превратился в «Я не буду спать, пока не выясню это» - сценарий :) Но я достаточно доволен базовым классом, который я представил здесь: http://bit.ly/bVYK1X –

ответ

2

Нет - вы не можете этого сделать. Деревья выражений растут так же глубоко, как сама лямбда.

+0

Спасибо за ответ. Я помню, где-то читал, что будущие версии .NET и C# дадут нам еще более динамичную среду программирования. Любые идеи, если следующий выпуск (5.0?) Может привести нас к тому, где это будет возможно? –

+0

Не так много динамического * языка *, но следующая версия C# должна быть оснащена очень гибким настраиваемым компилятором (написанным на C#), подобным тому, как работает Boo сейчас. –

+0

Хорошо, спасибо за ваш ответ. –

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