Создание выражения по методу экземпляра без экземпляра - PullRequest
0 голосов
/ 09 июня 2011

У меня есть универсальный класс, в котором есть метод 'Call' с универсальным типом возврата и лямбда-выражением в качестве параметра. Это должно быть сгенерировано с помощью отражения, и, поскольку типы неизвестны, мне нужно создать лямбда-выражение на долгий путь. У меня есть рабочее решение, перечисленное ниже, но мне не нравится выводить экземпляр из универсального класса, поскольку он является закрытым и выполняет некоторую логику при получении.

Класс:

public class Proxy<T>
{
    public TR Call<TR>(Func<T, TR> serviceInvoke)
    private T Instance
}

Использование отражения:

var serviceInstance = proxy.GetType().GetProperty("Instance", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(proxy, null);
var serviceMethod = type.GetMethod(rule.ServiceMethodName);
var parameters = serviceMethod.GetParameters().Select(parameterInfo => PropertyChainNavigator.GetValueForPropertyChain(((string)rule.Parameters[parameterInfo.Name]).Split(new[] { '.' }), context)).ToArray();
var thisParam = Expression.Constant(serviceInstance);
var valueParams = parameters.Select(Expression.Constant).ToList();
var call = Expression.Call(thisParam, serviceMethod, valueParams);
var func = Expression.Lambda(call, Expression.Parameter(type)).Compile();
var callMethod = proxy.GetType().GetMethods().Where(x => x.Name == "Call" && x.ReturnType != typeof(void)).First().MakeGenericMethod(serviceMethod.ReturnType);
result = callMethod.Invoke(proxy, new[] { func });

Нормальное использование:

var proxy = new Proxy<ITestClass>();
proxy.Call(x => x.Method);

Я попытался изменить Expression.Call, чтобы он не создавал экземпляр, но это работает только для статических методов. Кто-нибудь знает способ для меня, чтобы создать вызов, превратить его в лямбду и сделать его без ошибок

Ответы [ 2 ]

3 голосов
/ 10 июня 2011

Если вы используете лямбду вместо выражений, ваш текущий код будет выглядеть следующим образом:

var serviceInstance = …; // retrieve using reflection
proxy.Call(i => serviceInstance.CallMethod(parameters));

Обратите внимание, что лямбда принимает параметр i, но не использует его.Я предполагаю, что вы хотите вызвать метод непосредственно на i, то есть что-то вроде этого:

proxy.Call(i => i.CallMethod(parameters));

Для этого используйте значение Expression.Parameter() как thisParam:

var thisParam = Expression.Parameter(type, "i"); // the name is optional
var call = Expression.Call(thisParam, serviceMethod, valueParams);
var func = Expression.Lambda(call, thisParam).Compile();
0 голосов
/ 10 июня 2011
public class Proxy<T>
{
    public TR Call<TR>(Func<T, TR> serviceInvoke)
    {
        return serviceInvoke(Instance);
    }

    private T Instance;
}

Разве это не все, что тебе нужно? Зачем вам нужно получать экземпляр T, используя отражение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...