2012-05-24 5 views
1

У меня есть функция:Pass Expression Tree в качестве параметра метода

public void Execute(Expression<Action> expression) 
{ 
    var time = expression.Compile().Benchmark(); 

    var msg = string.Format("{0} took {1} to complete", 
     ReflectionHelper.GetComponentCallDetails().ToString(), 
     time.ToString(@"hh\:mm\:ss\.ff")); 

    Logger.Info(msg); 
} 

Делегат, который должен называться что-то вроде:

channels = GetAllChannelsImpl(maxResults); 

Я относительно новым для Expression Trees и не могу понять, способ передачи делегата Action методу.

Я был в состоянии сделать такую ​​же функциональность, используя

public void Execute(Action action) 
{ 
    var time = action.Benchmark(); 

    var msg = string.Format("{0} took {1} to complete", 
     ReflectionHelper.GetComponentCallDetails().ToString(), 
     time.ToString(@"hh\:mm\:ss\.ff")); 

    Logger.Info(msg); 
} 

и призванию

Execute(() => 
{ 
    channels = GetAllChannelsImpl(maxResults); 
}); 

Но я хотел бы использовать подход, основанный Expression Tree для того, чтобы исключить необходимость использования накладных расходов отражения, чтобы выяснить детали метода, вызванного для его регистрации.

Может ли кто-нибудь предложить правильный способ передать дерево выражений для указанного делегата действия в качестве параметра метода.

+0

Вы перегрузили метод 'Execute()', поэтому компилятор предпочитает версию с «Action» в версию с выражением «Expression ». Синтаксис вызова может быть таким же, если это не так. Вы пробовали 'new Expression (() => // и т. Д.)'? Это должно быть просто. – Jonno

ответ

2

Выражение лямбда само по себе не имеет типа. Фактический тип, который он принимает, выводится компилятором в зависимости от того, что вы пытаетесь назначить или применить. С учетом этого любые вызовы вашего метода Execute() с использованием простых lambdas будут неоднозначными, поскольку ваша лямбда будет совместима как Action или Expression<Action>. Вы должны были бы устранить эту проблему, явно указывая на тип, который вы ожидаете.

// assign to a variable 
Expression<Action> action1 =() => ...; 
Execute(action1); 

// cast 
Execute((Expression<Action>)(() => ...)); 

// use the constructor 
Execute(new Expression<Action>(() => ...)); 

Было бы лучше ИМХО устранить неоднозначную перегрузку и переименовать один из методов. Я бы рекомендовал переименовать перегрузку выражения в ExecuteExpression().

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