我试图在我的表达式树中添加一个额外的方法调用,但我对如何实现它略显困惑。以下是我目前正在使用的内容:
Word
我想要发生的是:
1)如果我的SetterInfo对象中的类型名称是ParcelFeat,并且属性名称以' G'开头。我想在valueParameter上调用ConvertParcelFeat,然后在返回时调用ChangeType。
2)如果类型的名称是ParcelFeat以外的任何名称,则调用Changetype正常,但不执行其他步骤
我感到困惑的是如何构建条件。我假设我在上面的代码中执行此操作的方式是错误的,我需要使用Expression.IfThen()之类的东西来构建条件。我也不确定如何将方法调用链接起来。
答案 0 :(得分:1)
您在Expression.IfThen中不需要,因为对于每个特定的SetterInfo,您只能组合一个特定的lambda实例。
只需在您的ExpressionTree的适当位置插入convertParcelFeatCall,一切都应该正常工作。
所以你的代码可能如下:
class Program
{
static void Main(string[] args)
{
var program = new Program();
var weightLambda = program.DoInternal("Weight").ToString()
== "(Param_0, Param_1) => (Convert(Param_0).Weight = Convert(ChangeType(Param_1, System.Object)))";
var goodiesLambda = program.DoInternal("Goodies").ToString()
== "(Param_0, Param_1) => (Convert(Param_0).Goodies = Convert(ChangeType(Param_1, ConvertParcelFeat(Param_1, \"Goodies\"))))";
Console.WriteLine("WeightLambda is Ok: {0}\nGoodiesLambda is Ok: {1}", weightLambda, goodiesLambda);
}
public Action<Object, Object> Do(string name)
{
return DoInternal(name).Compile();
}
public Expression<Action<object, object>> DoInternal(string name)
{
var info = new {Name = name, Type = typeof(Program)};
var propertyInfo = info.Type.GetProperty(info.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
var objParameter = Expression.Parameter(typeof(object));
var valueParameter = Expression.Parameter(typeof(object));
//This is the method call I'm trying to add
Expression toBeTypeChanged;
if (info.Name[0] == 'G' && info.Type.Name == "Program")
{
toBeTypeChanged = Expression.Call(ConvertParcelFeatMethod, valueParameter, Expression.Constant(info.Name));
}
else
{
toBeTypeChanged = Expression.Constant(propertyInfo.PropertyType);
}
var changeTypeCall = Expression.Call(ChangeTypeMethod, valueParameter, toBeTypeChanged);
var objCast = Expression.Convert(objParameter, info.Type);
var valueCast = Expression.Convert(changeTypeCall, propertyInfo.PropertyType);
var property = Expression.Property(objCast, propertyInfo);
var assignment = Expression.Assign(property, valueCast);
return Expression.Lambda<Action<object, object>>(assignment, objParameter, valueParameter);
}
public object Weight { get; set; }
public object Goodies { get; set; }
public static object ChangeType(object valueParameter, object constant)
{
return null;
}
public static object ConvertParcelFeat(object valueParameter, object constant)
{
return null;
}
public MethodInfo ConvertParcelFeatMethod
{
get { return typeof(Program).GetMethod("ConvertParcelFeat"); }
}
public MethodInfo ChangeTypeMethod
{
get { return typeof(Program).GetMethod("ChangeType"); }
}
}