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

如何从Func<T>委托中获取目标属性/字段的名称?

解决从Func委托中获取目标字段/属性名称的问题

你遇到的核心问题是:直接使用Func<T>委托时,lambda表达式会被编译成匿名方法(比如<InitialiseModel>b__7_0),丢失了原始的成员访问结构信息,所以无法直接提取目标字段名。要解决这个问题,需要改用表达式树Expression<Func<T>>来替代Func<T>,因为表达式树会保留lambda的语法结构,允许我们解析出目标成员的名称。

步骤1:修改PointerVariable<T>类,支持表达式树

将AddGetter方法的参数从Func<T>改为Expression<Func<T>>,同时添加解析成员名称的逻辑:

public class PointerVariable<T>
{
    private Func<T> _getter;
    public string TargetMemberName { get; private set; }

    public void AddGetter(Expression<Func<T>> getterExpression)
    {
        // 编译表达式为委托,保留原有的调用能力
        _getter = getterExpression.Compile();

        // 解析表达式,提取目标成员名称
        if (getterExpression.Body is MemberExpression memberExpr)
        {
            TargetMemberName = memberExpr.Member.Name;
        }
        // 处理值类型装箱转换的情况
        else if (getterExpression.Body is UnaryExpression unaryExpr && unaryExpr.Operand is MemberExpression operandMember)
        {
            TargetMemberName = operandMember.Member.Name;
        }
        else
        {
            throw new ArgumentException("传入的表达式必须是直接访问字段或属性的lambda");
        }
    }

    // 保留获取值的方法(可选)
    public T GetValue()
    {
        return _getter();
    }
}

步骤2:修改调用代码

调用AddGetter时,传入的lambda会自动被编译器转换为Expression<Func<T>>,无需额外改动:

public class Model : MonoBehaviour
{
    protected PointerVariable<bool> _isEnabledVar;
        
    public virtual void InitialiseModel() 
    {
       _isEnabledVar.AddGetter(() => enabled);
       // 直接获取目标字段名"enabled"
       string fieldName = _isEnabledVar.TargetMemberName;
    }
}

为什么Func<T>不行?

Func<T>是编译后的委托实例,仅包含指向IL代码的引用,没有保留lambda表达式的原始结构(比如“访问哪个字段”)。而Expression<Func<T>>是表达式树,它是对lambda语法结构的抽象描述,我们可以通过遍历表达式树节点,提取出成员访问的具体信息。

注意事项

  • 该方法仅适用于lambda直接访问字段/属性的场景(如() => enabled),如果lambda包含复杂逻辑(如() => enabled && IsReady),解析会失败,需根据实际场景扩展解析逻辑。
  • 只要lambda所在上下文有权访问目标成员,表达式树就能正常解析,无论成员是protected还是private。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:15:18