c# - Expression.Assign returns Func instead of Action -
i'm building small expression based property assigner.
the idea pretty simple, create action gets property object , assigns object property.
so if process expression:
public static action propertyassign(object sourceobject, object destobject, propertyinfo sourceproperty, propertyinfo destproperty) { expression source = expression.propertyorfield( expression.constant(sourceobject), sourceproperty.name); expression dest = expression.propertyorfield( expression.constant(destobject), destproperty.name); expression assign = expression.assign(dest, source); return (action)expression.lambda(assign).compile(); }
and try call it, exception telling expression.lambda of type func (where t property type)
since call assign expect have no remaining value on stack (so not returning property itself).
now if assign property using setmethod, :
public static action propertyassign(object sourceobject, object destobject, propertyinfo sourceproperty, propertyinfo destproperty) { expression source = expression.propertyorfield( expression.constant(sourceobject), sourceproperty.name); expression dest = expression.propertyorfield( expression.constant(destobject), destproperty.name); expression assign = expression.call( expression.constant(destobject), destproperty.setmethod, source); action assigner = (action)expression.lambda(assign).compile(); return assigner; }
in case function lambda.compile() returns action no parameter/return value expected.
so it's not blocking issue, i'm curious why assign operator returns value assigning property (where assign should calling setter method well).
also there way adapt first call return action instead of func?
the problem have because assignment operator in fact func
, whereas setter has void return.
normally avoid using expression.lambda
due problem (and casting).
try instead.
public static action propertyassign(object sourceobject, object destobject, propertyinfo sourceproperty, propertyinfo destproperty) { expression source = expression.property( expression.constant(sourceobject), sourceproperty); expression dest = expression.property( expression.constant(destobject), destproperty); expression assign = expression.assign(dest, source); return expression.lambda<action>(assign).compile(); }
this not give ambiguity in type of delegate want il return.
however particular piece of code seems pointless, cannot reuse il generated. suggest cache parameterized version of it.
public delegate void assign(tsource sourceobject, tdest destobject); public static assign propertyassign(tsource sourceobject, tdestdestobject, propertyinfo sourceproperty, propertyinfo destproperty) { var sourceobjectexpression = expression.parameter(sourceobject); var destpropertyexpression = expression.parameter(destproperty); expression source = expression.property( sourceobjectexpression, sourceproperty); expression dest = expression.property( destpropertyexpression, destproperty); expression assign = expression.assign(dest, source); var lambda = expression.lambda<assign>( assign, sourceobjectexpression, destpropertyexpression); return lambda.compile(); }
Comments
Post a Comment