Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an easy way to parse a (lambda expression) string into an Action delegate?

I have a method that alters an "Account" object based on the action delegate passed into it:

public static void AlterAccount(string AccountID, Action<Account> AccountAction) {
  Account someAccount = accountRepository.GetAccount(AccountID);
  AccountAction.Invoke(someAccount);
  someAccount.Save();
}

This works as intended...

AlterAccount("Account1234", a => a.Enabled = false);

...but now what I'd like to try and do is have a method like this:

public static void AlterAccount(string AccountID, string AccountActionText) {
  Account someAccount = accountRepository.GetAccount(AccountID);
  Action<Account> AccountAction = MagicLibrary.ConvertMagically<Action<Account>>(AccountActionText);
  AccountAction.Invoke(someAccount);
  someAccount.Save();
}

It can then be used like:

AlterAccount("Account1234", "a => a.Enabled = false");

to disable account "Account1234".

I've had a look at the linq dynamic query library, which seems to do more or less what I want but for Func type delegates, and my knowledge of Expression trees etc isn't quite good enough to work out how to achieve what I want.

Is there an easy way to do what I want, or do I need to learn expressions properly and write a load of code?

(The reason I want to do this is to allow an easy way of bulk updating account objects from a powershell script where the user can specify a lambda expression to perform the changes.)

like image 895
Whisk Avatar asked Apr 03 '09 16:04

Whisk


People also ask

How you can assign a lambda expression to a delegate?

Since a lambda expression is just another way of specifying a delegate, we should be able to rewrite the above sample to use a lambda expression instead of an anonymous delegate. In the preceding example, the lambda expression used is i => i % 2 == 0 . Again, it is just a convenient syntax for using delegates.

What is the difference between lambda expression and delegate?

The difference really is that a lambda is a terse way to define a method inside of another expression, while a delegate is an actual object type.

Is delegate a lambda?

Lambda expressions are also examples of delegates, which are collections of lines of code that can take inputs and optionally return outputs. We use the type Func<T> to define delegates that return an output, and Action<T> for delegates that will not return an output.

How do you read lambda expressions?

All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side hold the expression or statement block. The lambda expression x => x * 2 is read "x goes to 2 times x." This reduced the no.


2 Answers

The Dynamic LINQ library is a fine choice, as it'll generate expressions you can compile to code in a lightweight fashion.

The example you provided actually produces a boolean -- so you should be able to ask for a Func and it might sort it out.

Edit: This of course is wrong, as Expressions don't have assignment in them at all.

So, another potential way is to take two lambdas. One to find the property you want, one to provide a value:

(a => a.AccountId), (a => true)

Then use reflection to set the property referenced in the first lambda with the result of the second one. Hackish, but it's still probably lightweight compared to invoking the C# compiler.

This way you don't have to do much codegen yourself - the expressions you get will contain most everything you need.

like image 75
MichaelGG Avatar answered Oct 18 '22 21:10

MichaelGG


You may try this: Dynamic Lambda Expressions Using An Isolated AppDomain

It compiles a lambda expression using CodeDOM compiler. In order to dispose the in-memory assembly that gets created, the compiler runs on an isolated AppDomain. For the passing the expression through the domain boundary, it has to be serialized. Alas, Expression<> is not Serializable. So, a trick has to be used. All the details are explained in the post.

I'm the author of that component, by the way. I would like very much to hear your feedback from it.

like image 28
jpbochi Avatar answered Oct 18 '22 19:10

jpbochi