如何获取传入Expression的成员名称以优化ToString重写逻辑?
解决方法
问题出在Expression<Func<MyObject, object>>的表达式体可能是UnaryExpression(当属性是值类型时,会自动插入装箱操作),所以不能直接取exp.Body.Member,需要先解析出真正的MemberExpression。
修改后的GetProp方法实现如下:
private string GetProp(Expression<Func<MyObject, object>> exp) { // 解析表达式,获取真正的成员访问表达式 MemberExpression memberExp; if (exp.Body is UnaryExpression unaryExp) { // 处理值类型装箱的情况,取Operand作为成员表达式 memberExp = unaryExp.Operand as MemberExpression; } else { // 引用类型直接转成MemberExpression memberExp = exp.Body as MemberExpression; } // 提取属性名称 var propName = memberExp.Member.Name; // 获取属性值 var propValue = exp.Compile().Invoke(this); return $"{propName}={propValue}"; }
完整的MyObject类代码
public class MyObject { public string Prop1 { get; set; } = "value1"; public string Prop2 { get; set; } = "value2"; // 可添加值类型属性测试,比如int类型 public int Prop3 { get; set; } = 123; public override string ToString() { var parts = new[] { GetProp(x => x.Prop1), GetProp(x => x.Prop2), GetProp(x => x.Prop3) }; return string.Join(",", parts); } private string GetProp(Expression<Func<MyObject, object>> exp) { MemberExpression memberExp; if (exp.Body is UnaryExpression unaryExp) { memberExp = unaryExp.Operand as MemberExpression; } else { memberExp = exp.Body as MemberExpression; } var propName = memberExp.Member.Name; var propValue = exp.Compile().Invoke(this); return $"{propName}={propValue}"; } }
说明
- 当传入的表达式是值类型属性(如
int Prop3),编译器会生成Convert(x.Prop3)这样的UnaryExpression,所以需要通过unaryExp.Operand拿到真正的成员访问节点。 - 引用类型属性则直接是MemberExpression,无需额外处理。
- 这样不管是引用类型还是值类型属性,都能正确提取属性名称并生成
属性名=属性值的字符串。
内容的提问来源于stack exchange,提问作者devklick
相关产品推荐
相关产品推荐

