Oğuzhan Soykan
Oğuzhan Soykan

Reputation: 2690

ParameterExpression to Object Casting with Reflection

I want to cast any object from ParameterExpression class.

This is sample code (and pseudo what i want to say) :

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:

This is my method body:

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

I want to manipulate requestDto.

Upvotes: 2

Views: 818

Answers (1)

xanatos
xanatos

Reputation: 111870

Here it is... With this you should be able to extract your requestDto.

Note that you don't need the Invoke() when you call compiled expressions.

operation.Compile()(OpenNewChannel);

is enough.

Now, to extract the 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;
}

Upvotes: 1

Related Questions