Shimmy Weitzhandler
Shimmy Weitzhandler

Reputation: 104721

Resolve Linq.Expressions.NewExpression?

How can I 'compile' the NewExpression to instantiate the pointed new expression?

Do I have to construct the object manually or I can just get the constructed object as an argument?

Gonna update my question with an example soon.

class Obj
{
  public async Task ParseAsync<TObj>(Expression<Func<TObj, Task>> pointedMethod)
  {
    var method = pointedMethod.Body as MethodCallExpression;
    var arg = method.Arguments[0];
    var newExp = arg as NewExpression;

    //This is what I need:
    User = newExp.ConstructObject();
    await Task.FromResult((object)null);
  }

  public async Task MyMethod(User user)
  {
    await Task.FromResult((object)null);
  }
}

static void Main(string[] args)
{
  var obj = new Obj();

  obj.ParseAsync<Obj>(o => o.MyMethod(new User())).Wait();
}

Notes: At execution time, there won't be a proper reference to TObj, the item has to be constructed solely from the arguments provided to the ParseAsync function.
Since I have a NewExpression it means that the object (User in my example) is capable of being constructed.
The question is if there is a way of instantiating the object without walking manually finding the constructor and calling it etc.

Upvotes: 4

Views: 1641

Answers (1)

Shimmy Weitzhandler
Shimmy Weitzhandler

Reputation: 104721

Answer was originally answered by @dasblinkenlight, I have no clue why he deleted it, it just worked. Anyway should he choose to undelete his answer and I'll delete mine and credit him!

Anyway for the reference:

The answer depends on whether or not the NewExpression in question references any parameters, and if you have access to these parameter expressions in case it does.

If NewExpression has no parameters, simply construct a lambda expression from it, compile, and run:

NewExpression myNewExpression = ... // You have this
var instantiator = (Func<MyResultType>)Expression
    .Lambda<Func<MyResultType>>(myNewExpression)
    .Compile();
MyResultType res = instantiator();

Upvotes: 3

Related Questions