Program.cs代码:
class Program
{
private static void Main(string[] args)
{
var st = new Student { Id = 10, Name = "爱因斯坦" }
ParameterExpression paraExpr = Expression.Parameter(st.GetType())
//访问 st=>st.Name
PropertyInfo idProp = st.GetType().GetProperty("Id")
BlockExpression idExpr = CreatePropertyAccesorExpression(idProp, paraExpr, null)
Expression<Func<Student, int>> idlambda = Expression.Lambda<Func<Student, int>>(idExpr, paraExpr)
//生成的表达式大意为:"st=>st.Id"
Func<Student, int> idFunc = idlambda.Compile()
int idValue = idFunc(st)
Console.WriteLine("id= " + idValue)
//现在访问 st=>st.Location.Row
PropertyInfo localProp = st.GetType().GetProperty("Location")
BlockExpression localExpr = CreatePropertyAccesorExpression(localProp, paraExpr, null)
//生成的表达式大意为:"st.Location!=null?st.Location:null"
PropertyInfo rowProp = localProp.PropertyType.GetProperty("Row")
BlockExpression rowExpr = CreatePropertyAccesorExpression(rowProp, localExpr, null)
//生成lambda: st=>(rowExpr表达式块)
Expression<Func<Student, int>> rowlambda = Expression.Lambda<Func<Student, int>>(rowExpr, paraExpr)
Func<Student, int> rowFunc = rowlambda.Compile()
int rowValue = rowFunc(st)
Console.WriteLine("rowValue= " + rowValue)
Console.ReadKey()
}
private static BlockExpression CreatePropertyAccesorExpression(PropertyInfo prop, Expression parentExpr,
object defaultValue)
{
//默认值
if (defaultValue == null && prop.PropertyType.IsValueType)
{
defaultValue = Activator.CreateInstance(prop.PropertyType)
}
//默认返回Expression
ConstantExpression defaultExpr = Expression.Constant(defaultValue, prop.PropertyType)
//测试当前属性的“父属性”是否非空
BinaryExpression test = Expression.NotEqual(parentExpr, Expression.Constant(null))
//“父属性”非空时的返回值
MemberExpression propExpr = Expression.Property(parentExpr, prop)
LabelTarget labelTarget = Expression.Label(prop.PropertyType)
//局部变量,用于存放最终的返回值
ParameterExpression locExpr = Expression.Variable(prop.PropertyType)
//测试并赋值
ConditionalExpression ifesleTestExpr = Expression.IfThenElse(test, Expression.Assign(locExpr, propExpr),
Expression.Assign(locExpr, defaultExpr))
//返回值
GotoExpression retExpr = Expression.Return(labelTarget, locExpr)
LabelExpression labelExpr = Expression.Label(labelTarget, locExpr)
BlockExpression block = Expression.Block(
new[] { locExpr },
ifesleTestExpr,
retExpr,
labelExpr
)
return block
}
}
运行结果如图:
