Edit I think I can ask better (no code needed at all in this case). So the question in general is: how to use an Expression tree to build a call to a generic method (Select<TEntity,TResult> in my case) when TResult is created at runtime? Ignore all the code and text below, that was unclear version of the question, left it to not confuse those who answered.
I need an example how to build an Expression tree for a "Select" call. The problem is that I don't know the result type at compile time (it can be defined by user through some GUI in runtime). Here is some code of how I'm trying to do this (remember I can't use any generics)
class Pet {
public int Id { get; set; }
public string Name { get; set; }
}
Using this class in Main:
List<Pet> list = new List<Pet>();
Expression eList = Expression.Constant(list);
ParameterExpression pe = Expression.Parameter(typeof(Pet), "p");
MethodInfo method = typeof(Program).GetMethod("CreateObject", BindingFlags.Static | BindingFlags.NonPublic);
var properties = typeof(Pet).GetProperties().Where(pi => pi.Name == "Name"); //will be defined by user
Expression selectorBody = Expression.Call(method, Expression.Constant(properties));
Expression selector = Expression.Lambda(selectorBody, pe);
Expression res = Expression.Call(typeof(Enumerable), "Select", new[] { typeof(Pet), CreateType(properties) }, eList, selector);
What I'm trying to do is create a Type at runtime using Reflection.Emit (method "CreateType" in code above, it is used in some of my projects and looks fine) and somehow pass it to call to "Select", but I get exception:
No generic method 'Select' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments.
Any suggestions?
Upd my real problem is building an Expression tree for a "Join" call for runtime types which is more complicated, so i decided to ask about "Select", because I'm having the same exception in the last line (Expression.Call(...))
Upd2 included my helper methods and edited main code, however this is not the main problem.
static Type CreateType(IEnumerable<PropertyInfo> properties) {
TypeBuilder typeBuilder = CreateTypeBuilder("ResultDynamicAssembly", "ResultModule", "ResultType");
foreach (PropertyInfo propertyInfo in properties) {
CreateAutoImplementedProperty(typeBuilder, propertyInfo.Name, propertyInfo.PropertyType);
}
return typeBuilder.CreateType();
}
static object CreateObject(IEnumerable<PropertyInfo> properties) {
Type type = CreateType(properties);
return Activator.CreateInstance(type);
}