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

如何获取委托中对象初始化时赋值属性的源属性名称?

获取对象初始化表达式中的属性映射源名称

要获取Foo所赋值的源属性名称(比如示例中的ObjA.Bar),必须使用表达式树——因为普通的Func<ObjA, ObjB>委托编译后会丢失元数据结构,只有表达式树能保留初始化逻辑的完整信息。

实现步骤

  1. 将原委托定义为Expression<Func<ObjA, ObjB>>类型,而非直接的Func<ObjA, ObjB>,这样才能保留表达式结构。
  2. 解析表达式树的对象初始化节点,匹配目标属性(如Foo)对应的赋值表达式。
  3. 提取赋值表达式中的源属性路径。

代码示例

首先定义实体类:

public class ObjA
{
    public string Bar { get; set; }
    public int Bar1 { get; set; }
}

public class ObjB
{
    public string Foo { get; set; }
    public int Foo1 { get; set; }
}

定义表达式并编写解析方法:

// 定义带表达式树的映射逻辑
Expression<Func<ObjA, ObjB>> mapExpr = a => new ObjB { Foo = a.Bar, Foo1 = a.Bar1 };

// 解析目标属性对应的源属性名称
public static string GetSourceProperty(Expression<Func<ObjA, ObjB>> expr, string targetPropName)
{
    if (expr.Body is not NewExpression initExpr)
        throw new ArgumentException("仅支持对象初始化表达式");

    // 找到目标属性在初始化列表中的位置
    var propIndex = initExpr.Members
        .Select(m => m.Name)
        .ToList()
        .IndexOf(targetPropName);

    if (propIndex == -1)
        throw new ArgumentException($"未找到目标属性:{targetPropName}");

    // 获取赋值的源表达式
    var sourceExpr = initExpr.Arguments[propIndex];

    // 解析单层属性(多层属性可扩展递归逻辑)
    if (sourceExpr is MemberExpression memberExpr)
    {
        var paramName = ((ParameterExpression)memberExpr.Expression).Name;
        var propName = memberExpr.Member.Name;
        return $"{paramName}.{propName}";
    }

    throw new NotSupportedException("暂不支持复杂表达式赋值");
}

调用示例:

var sourceProp = GetSourceProperty(mapExpr, "Foo");
Console.WriteLine(sourceProp); // 输出:a.Bar

扩展说明

如果需要支持多层属性(如a.NestedObj.Bar),可以给解析方法添加递归逻辑,逐层遍历MemberExpression拼接完整路径:

private static string GetPropertyPath(Expression expr)
{
    if (expr is MemberExpression memberExpr)
    {
        var parentPath = GetPropertyPath(memberExpr.Expression);
        return string.IsNullOrEmpty(parentPath) 
            ? memberExpr.Member.Name 
            : $"{parentPath}.{memberExpr.Member.Name}";
    }
    if (expr is ParameterExpression paramExpr)
    {
        return paramExpr.Name;
    }
    throw new NotSupportedException("不支持的表达式类型");
}

修改GetSourceProperty方法中返回值为GetPropertyPath(sourceExpr)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:45:18