Итак, немного поэкспериментируем с деревьями выражений.Вот идея: я хочу вернуть объект Func<long, byte?, object>
.В зависимости от типа, для которого я хочу использовать функцию, у меня будет один из двух методов: LoadById(long, byte?)
или LoadByID(long)
.Оба возвращают объект.Поэтому я пытаюсь сделать следующее: в зависимости от того, реализует ли тип определенный интерфейс, я использую либо classToUseFunctionOn.LoadById(long, byte?)
, либо classToUseFunctionOn.LoadByID(long)
.Итак, в основном я хочу получить следующий код, если он реализует интерфейс: (длинный идентификатор, байт? Параметры) => новый TestFacade (). LoadById (идентификатор, параметры) и (длинный идентификатор, байт? Параметры) => новыйTestFacade (). LoadByID (идентификатор).Я просто не уверен, как это сделать.Это идет не так в последние несколько строк.Лямбда-вызов указывает, что количество параметров неверно.Ниже приведен код, который у меня есть:
private static Func GetDataExtractorForTypeWithId(Type type)
{
var paramId = Expression.Parameter(typeof(long), "id");
ParameterExpression paramOptions = null;
//gets the ConstructorInfo for the constructor of type T with a single parameter of type IDataReader
var facadetype = GetFacadeType(type.Name);
MethodInfo loadMethod;
var linkedEntitiesInterface = facadetype.GetInterface(typeof(IFacadeLoadLinkedEntities).Name);
var lamdaParameterExpressions = new List() { paramId };
if (linkedEntitiesInterface != null)
{
loadMethod = facadetype.GetMethod("LoadById");
paramOptions = Expression.Parameter(linkedEntitiesInterface.GetGenericTypeDefinition().GenericTypeArguments[1], "options");
lamdaParameterExpressions.Add(paramOptions);
}
else
{
paramOptions = Expression.Parameter(typeof(byte?));
loadMethod = facadetype.GetMethod("LoadByID", new Type[1]{typeof(long)});
}
var facadeConstructor = facadetype.GetConstructor(new Type[0]);
var newFacade = Expression.New(facadeConstructor);
var callLoad = Expression.Call(newFacade, loadMethod, lamdaParameterExpressions);
lamdaParameterExpressions.Add(paramOptions);
var returnValue = Expression.Parameter(typeof(object));
lamdaParameterExpressions.Add(returnValue);
var entityVariable = Expression.Variable(typeof(object), "entity");
Expression.Assign(entityVariable, callLoad);
var lambda = Expression.Lambda>(
entityVariable, lamdaParameterExpressions.ToArray());
//compiles the Expression to a usable delegete.
return lambda.Compile();
}