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
}
}
运行结果如图: