I've simplified this a lot to get to the core of the issue:
I have a control that needs properties populated. Unfortunately the values are all sitting in CodeDom.CodeStatements.
So I literally have to fish for the values by using code like this :
static string GenerateCode(CodeStatementCollection statements, Control control)
{
var writer = new StringWriter();
var compiler = new CSharpCodeProvider();
foreach (CodeStatement statement in statements)
{
var codeAssignStatement = statement as System.CodeDom.CodeAssignStatement;
var left = codeAssignStatement?.Left as System.CodeDom.CodePropertyReferenceExpression;
if (left == null)
{
continue;
}
var right = codeAssignStatement.Right as System.CodeDom.CodeObjectCreateExpression;
if (right == null)
{
continue;
}
var expressionWriter = new StringWriter();
compiler.GenerateCodeFromExpression(right,expressionWriter,null);
var expression = expressionWriter.ToString();
control.SetPropertyValue(left.PropertyName, expression);
compiler.GenerateCodeFromStatement(statement, writer, null);
}
return writer.ToString();
}
Notice that the code is using reflection, SetPropertyValue is actually an extension method:
public static void SetPropertyValue(this object obj, string propName, object value)
{
obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}
But this only works if the value is a literal value, not an expression.
At runtime, what I'm getting from the CodeDom statement is an expression, also the control is a button.
Button.Location = New System.Drawing.Point(12,12);
So in the above code sample, expression = "New System.Drawing.Point(12,12)"
Now I don't want to have to run through a series of IF statements to first determine the type.
Is it possible to use reflection to set a property based on an expression?
If not, is it possible to use some kind of Eval function in .net to pull this off?
I think you can try LINQ Expression. https://msdn.microsoft.com/en-us/library/bb335710(v=vs.110).aspx
Change you method to like below:
Configure and compile the delegate function in expression and call it in your SetPropertyValue().
To create code from a script you would need to dynamically compile the method.
The first thing you would have to do is compile the method into a
MethodInfo
. You can create a method to accomplish this.Once you have this done you can use it like this.
Now that
method
variable holds yourMethodInfo
, so you just need to invoke it.