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

C#如何向inline内联函数传递变量同时获取属性名与对应值

问题解答

结论

完全可以实现,有两种主流方案可以满足你的简化写法需求,其中C# 10+提供的语言特性可以100%匹配你期望的调用写法。

方案1:C# 10+ 原生特性支持(推荐)

利用[CallerArgumentExpression]编译时特性,编译器会自动将你传入参数的表达式文本作为键注入,运行时无额外开销,写法和你预期完全一致:

using System.Runtime.CompilerServices;

void WhatIWouldLike_SetPreferences()
{
    void f(object value, [CallerArgumentExpression(nameof(value))] string key = null)
    {
        Preferences.Set(key, value?.ToString() ?? string.Empty);
    }

    // 调用方式完全符合你的预期,无需手动传入属性名
    f(Pressure);
    f(Temperature);
}

该方案要求项目的语言版本设置为C# 10及以上,新版本Xamarin Forms、.NET MAUI项目均默认支持该特性。

方案2:表达式树兼容方案

如果你的项目暂时无法升级到C# 10,可以用表达式树实现,仅需要在调用时加lambda前缀,比原有双参数写法仍简洁很多:

using System.Linq.Expressions;

void WhatIWouldLike_SetPreferences()
{
    void f(Expression<Func<object>> expr)
    {
        MemberExpression memberExpr;
        // 处理值类型属性的装箱表达式
        if (expr.Body is UnaryExpression unaryExpr)
        {
            memberExpr = unaryExpr.Operand as MemberExpression;
        }
        else
        {
            memberExpr = expr.Body as MemberExpression;
        }

        if (memberExpr == null)
            throw new ArgumentException("仅支持传入属性访问表达式");
        
        string key = memberExpr.Member.Name;
        object value = expr.Compile().Invoke();
        Preferences.Set(key, value?.ToString() ?? string.Empty);
    }

    // 调用方式仅需增加lambda前缀
    f(() => Pressure);
    f(() => Temperature);
}

该方案存在极少量的表达式编译开销,对于Preference这类低频IO场景完全可以忽略,不会影响运行性能。

补充说明

C#默认是值传递语义,如果你不借助上述语言特性,直接传f(Pressure)的话,方法仅能收到属性的值副本,无法获取属性对应的元信息,因此无法实现你要的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:24:02