我已經簡化了很多以達到問題的核心:評估代碼內聯(或使用反射)
我有一個需要填充屬性的控件。不幸的是,這些值都在CodeDom.CodeStatements中。
所以我真的有使用這樣的代碼來撈取值:
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();
}
請注意,該代碼是使用反射,SetPropertyValue實際上是一個擴展方法:
public static void SetPropertyValue(this object obj, string propName, object value)
{
obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}
但這隻有在值是文字值時纔有效,而不是表達式。
在運行時,正是我從CodeDOM的聲明得到的是一種表達,也是控制是一個按鈕。
Button.Location = New System.Drawing.Point(12,12);
所以上面的代碼示例中,表達=「新System.Drawing.Point(12,12)」
現在我不希望有通過一系列的運行IF語句第一確定類型。
是否有可能使用反射來設置基於表達式的屬性?
如果沒有,是否有可能使用某種eval函數在.NET拉這一關?
你真聰明!這工作完美。非常感謝你! –