截至2020年
此辅助方法将优雅地检索任何表达式值,而无需“ compile hack”:
public static object GetMemberExpressionValue (MemberExpression expression)
{
var dependencyChain = new List<MemberExpression>();
var pointingExpression = expression;
while (pointingExpression != null)
{
dependencyChain.Add(pointingExpression);
pointingExpression = pointingExpression.Expression as MemberExpression;
}
if (!(dependencyChain.Last().Expression is ConstantExpression baseExpression))
{
throw new Exception(
$"Last expression {dependencyChain.Last().Expression} of dependency chain of {expression} is not a constant." +
"Thus the expression value cannot be found.");
}
var resolvedValue = baseExpression.Value;
for (var i = dependencyChain.Count; i > 0; i--)
{
var expr = dependencyChain[i - 1];
resolvedValue = new PropOrField(expr.Member).GetValue(resolvedValue);
}
return resolvedValue;
}
PropOrField
类:
public class PropOrField
{
public readonly MemberInfo MemberInfo;
public PropOrField (MemberInfo memberInfo)
{
if (!(memberInfo is PropertyInfo) && !(memberInfo is FieldInfo))
{
throw new Exception(
$"{nameof(memberInfo)} must either be {nameof(PropertyInfo)} or {nameof(FieldInfo)}");
}
MemberInfo = memberInfo;
}
public object GetValue (object source)
{
if (MemberInfo is PropertyInfo propertyInfo) return propertyInfo.GetValue(source);
if (MemberInfo is FieldInfo fieldInfo) return fieldInfo.GetValue(source);
return null;
}
public void SetValue (object target, object source)
{
if (MemberInfo is PropertyInfo propertyInfo) propertyInfo.SetValue(target, source);
if (MemberInfo is FieldInfo fieldInfo) fieldInfo.SetValue(target, source);
}
public Type GetMemberType ()
{
if (MemberInfo is PropertyInfo propertyInfo) return propertyInfo.PropertyType;
if (MemberInfo is FieldInfo fieldInfo) return fieldInfo.FieldType;
return null;
}
}