You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需对象实例获取非静态属性的DisplayNameAttribute值?

嘿,针对你要无需实例化对象就能获取类中非静态成员的DisplayNameAttribute值这个需求,我整理了几个比你当前表达式树方案更简洁清晰的实现,一起来看看:

场景回顾

先明确你的目标场景:给定如下类,要获取someVar属性上DisplayNameAttribute的DisplayName值:

public class MyClass 
{ 
    [DisplayName("MyName")] 
    public int someVar { get; set; } 
}

方案1:反射+nameof(极致简洁,兼顾类型安全)

这个方案直接通过反射获取类型的属性信息,用nameof避免硬编码字符串,既简洁又能在编译时检查属性是否存在:

public static string GetDisplayName<T>(string propertyName)
{
    var property = typeof(T).GetProperty(propertyName);
    if (property == null) return propertyName;
    
    var displayAttr = property.GetCustomAttribute<DisplayNameAttribute>();
    return displayAttr?.DisplayName ?? property.Name;
}

// 调用方式(完全类型安全):
var name = GetDisplayName<MyClass>(nameof(MyClass.someVar));

优点:代码量极少,逻辑直白,nameof保证了属性名不会因为重构出错。

方案2:优化后的表达式树方案(强类型安全,无字符串)

如果你希望完全避免字符串(哪怕是nameof),可以优化你原本的表达式树实现,修复值类型属性的转换问题,让代码更健壮:

public static string GetDisplayName<T>(Expression<Func<T, object>> expr)
{
    // 处理值类型属性转object时的UnaryExpression包装
    var memberExpr = expr.Body switch
    {
        UnaryExpression unary => unary.Operand as MemberExpression,
        MemberExpression member => member,
        _ => null
    };

    if (memberExpr?.Member is not PropertyInfo property) 
        return string.Empty;

    var displayAttr = property.GetCustomAttribute<DisplayNameAttribute>();
    return displayAttr?.DisplayName ?? property.Name;
}

// 调用方式(完全强类型,编译时校验):
var name = GetDisplayName<MyClass>(x => x.someVar);

优点:完全不需要写属性名字符串,编译时就能发现属性名错误,适合对类型安全要求极高的场景。

方案对比与选择

  • 如果你追求最简代码:优先选方案1,代码少、易理解,nameof已经足够保证类型安全。
  • 如果你需要绝对的强类型校验(不想出现任何字符串形式的属性名):选方案2,虽然代码稍多,但能在编译阶段拦截错误。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:59:35