I am trying to make some Expressions where I will be using a lambda to create two methods: a selector and condition. Simplified the usage is condition(selector(data))
, but the intemediate type is only known at runtime. I have the following code which works as long as the intemediate type is object, but at runtime I know the real type and would like to use that.
public static ICondition<TData> GetRelayConditionByReflection(string name, string message, string assemblyName,
string fullyQualifiedName, string conditionMethodName, string selectorMethodName) {
var asm = Assembly.LoadFrom(assemblyName);
var type = asm.GetType(fullyQualifiedName);
var selectorMi = type.GetMethod(selectorMethodName, BindingFlags.Static | BindingFlags.Public);
var conditionMi = type.GetMethod(conditionMethodName, BindingFlags.Static | BindingFlags.Public);
var tCondType = selectorMi.ReturnType;
var returnType = typeof(RelayCondition<,>);
var typeArgs = new[] { typeof(TData), tCondType };
var paramTData = Expression.Parameter(typeof(TData), "data");
var selector = Expression.Lambda<Func<TData, object>>(
Expression.Call(selectorMi, paramTData), paramTData).Compile();
var paramTCondition = Expression.Parameter(tCondType, "condition");
var condition = Expression.Lambda<Func<object, bool>>(
Expression.Call(conditionMi, paramTCondition), paramTCondition).Compile();
return (ICondition<TData>)Activator.CreateInstance(returnType.MakeGenericType(typeArgs), name, condition, message, selector);
}
Specifically, there is Expression.Lambda<Func<TData, object>>
and Expression.Lambda<Func<object, bool>>
where object
currently only allows the intemediate type to be object.
Is it possible to create this with a type known only at runtime? I am open for other approaches for the entire problem, as long as performance isn't attrocius.
If you don't need implicit downcasting (for example declaring a
Func<object>
when in truth you method returns aFunc<Foo>
), you can use the non-genericExpression.Lambda()
method. It returns aLambdaExpression
, but in truth it returns aExpression<>
ofFunc<>
or ofAction
downcasted toLambdaExpression
(Expression<>
is a subclass ofLambdaExpression
), so:now
condition
is aDelegate
, but in truth it is aFunc<>
(or anAction
if it had a return typevoid
).