2015-03-31 5 views
2

Я хочу, чтобы любой объект из класса ParameterExpression.ParameterExpression to Object Casting with Reflection

Это пример кода (и псевдо, что я хочу сказать):

public void Execute(Expression<Action<TService>> operation) 
{ 
    try 
    { 

     var param = operation.Parameters[0]; //myparameter to cast 
     var obj = param as AnyCastObject; // I want to cast 
     DoSomething(obj); // and do something this object without losing any assigned propery. 

     operation.Compile().Invoke(OpenNewChannel); 
    } 
    finally 
    { 
     CloseChannel(); 
    } 
} 

Edit:

Это мой метод тела:

Execute(x => x.UserAuthentication(requestDto));

Я хочу манипулировать requestDto.

+0

Вы, кажется, не понимают, как работают выражения. 'param' не является« значением »параметра, это« параметр »в смысле« дескриптор параметра ». «литье» «дескриптора параметра» не имеет никакого смысла. Что вы можете сделать, так это создать новое дерево выражений, в котором значение «value» параметра передается на что-то другое, а затем что-то делается. – xanatos

+0

Я знаю, что параметр не является ценностью. Я пишу этот пример для псевдо, что я хочу сказать. Но я не понимаю, что вы говорите. –

+0

Итак, что вы хотите бросить? Вы хотите иметь «новое» 'ParameterExpression' для другого типа (' MyService' вместо 'TService')? Вы хотите изменить тип параметра операции из 'TService' в' MyService'? Или что? – xanatos

ответ

1

Вот оно ... С этим вы сможете извлечь requestDto.

Обратите внимание, что при вызове скомпилированных выражений не требуется Invoke().

operation.Compile()(OpenNewChannel); 

достаточно.

Теперь, чтобы извлечь requestDto:

// Works for Execute(x => x.UserAuthentication(something)) 
// where something must be a constant value, a variable, 
// a field, a property 
var param = operation.Parameters[0]; //myparameter to cast 

var body = operation.Body as MethodCallExpression; 

if (body == null || body.Object != param || body.Method.Name != "UserAuthentication") 
{ 
    throw new NotSupportedException(); 
} 

// If you have a type for the parameter, replace it here: 
// object -> yourtype 
object requestValue; 

var constantExpression = body.Arguments[0] as ConstantExpression; 

if (constantExpression == null) 
{ 
    // For nearly all the types of expression, the only way 
    // to extract the final value is to compile them and then 
    // execute them (the execution is the last "()") 

    // If you have a type for the parameter, replace it here: 
    // Func<object> -> Func<yourtype> 
    requestValue = Expression.Lambda<Func<object>>(body.Arguments[0]).Compile()(); 
} 
else 
{ 
    // Constant expression values can be directly extracted 

    // If you have a type for the parameter, replace it here: 
    // (yourtype)constantExpression.Value 
    requestValue = constantExpression.Value; 
} 
+0

Отлично! Это точно так, как я хочу, большое спасибо. –