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

如何从集合中的属性获取正确的nameof()结果?

获取嵌套属性名称的替代方案

嘿,我懂你的需求——你想让nameof()返回类似"Items.Sku"这样的嵌套属性路径,但可惜原生nameof()做不到这一点,它只能解析单个标识符,没办法处理order.Items.Sku这种链式访问的场景。不过我们可以用表达式树来实现这个功能,下面给你两种实用的解决方案:

方案1:通用表达式树解析方法(类型安全,推荐)

写一个通用工具方法,通过表达式树解析嵌套属性的完整路径,既能保留类型安全,又能自动获取正确的属性名:

public static string GetNestedPropertyName<T>(Expression<Func<T>> propertyExpression)
{
    var memberExpr = propertyExpression.Body as MemberExpression;
    if (memberExpr == null)
        throw new ArgumentException("输入必须是属性访问的表达式");

    var propertyNames = new List<string>();
    // 从最内层属性往上遍历,收集所有属性名称
    while (memberExpr != null)
    {
        propertyNames.Add(memberExpr.Member.Name);
        memberExpr = memberExpr.Expression as MemberExpression;
    }

    // 反转后拼接成完整路径
    propertyNames.Reverse();
    return string.Join(".", propertyNames);
}

使用示例

因为Items是List<Item>,我们可以通过索引器(比如[0])代表集合中的元素,表达式树会自动解析到Sku属性:

Requires.That(order.Items.TrueForAll(x => !string.IsNullOrEmpty(x.Sku)), 
    GetNestedPropertyName(() => order.Items[0].Sku), 
    "Sku must contain a value");

这个方法返回的结果就是"Items.Sku",完全符合你的需求。而且如果后续修改了Item.Sku的名称,编译器会自动报错,避免硬编码带来的维护问题。

方案2:手动拼接nameof结果(简单但不够优雅)

如果你的场景比较简单,也可以直接手动拼接两个nameof的结果,虽然不够灵活,但胜在简单:

Requires.That(order.Items.TrueForAll(x => !string.IsNullOrEmpty(x.Sku)), 
    $"{nameof(order.Items)}.{nameof(Item.Sku)}", 
    "Sku must contain a value");

这种方式的缺点是,当属性名修改时,你需要确保两处nameof都同步更新,否则会出现不一致的情况。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:47:35