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

如何简化泛型调用?省略冗长的PropertyHelper属性获取代码

问题描述

我现有一段调用代码:

AddConversion<string>(
    PropertyHelper<PlayerCreditsBalanceWriter>.GetProperty(x => x.Credits), 
    i => (long)i + ".0" );

希望简化为以下形式:

AddConversion<string>(x => x.Credits, i => (long)i + ".0" );

请问如何通过传递当前类的方式,避免使用冗长的PropertyHelper<T>.GetProperty代码?

附PropertyHelper类实现:

public static class PropertyHelper<T>
{
    public static PropertyInfo GetProperty<TValue>(
        Expression<Func<T, TValue>> selector)
    {
        Expression body = selector;
        
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }

        return body.NodeType switch
        {
            ExpressionType.MemberAccess => (PropertyInfo)((MemberExpression)body).Member,
            _ => throw new InvalidOperationException()
        };
    }
}
解决方案

核心思路是让AddConversion直接接收属性选择器表达式,内部自动完成PropertyInfo的提取,无需外部显式调用PropertyHelper。

方法1:重载AddConversion方法

假设原AddConversion方法签名如下(基于调用逻辑推断):

public void AddConversion<TResult>(PropertyInfo property, Func<object, TResult> converter)

新增泛型重载方法,内部调用PropertyHelper获取属性信息后转发给原方法:

// 基础重载,适配object类型返回的属性选择器
public void AddConversion<T, TResult>(Expression<Func<T, object>> propertySelector, Func<object, TResult> converter)
{
    var propertyInfo = PropertyHelper<T>.GetProperty(propertySelector);
    AddConversion<TResult>(propertyInfo, converter);
}

// 精确类型重载,避免值类型装箱
public void AddConversion<T, TValue, TResult>(Expression<Func<T, TValue>> propertySelector, Func<object, TResult> converter)
{
    var propertyInfo = PropertyHelper<T>.GetProperty(propertySelector);
    AddConversion<TResult>(propertyInfo, converter);
}

此时即可直接用目标形式调用,编译器会自动推断x的类型为PlayerCreditsBalanceWriter:

AddConversion<string>(x => x.Credits, i => (long)i + ".0");

方法2:内联属性提取逻辑

如果不想依赖PropertyHelper,可以将提取PropertyInfo的逻辑直接写到重载方法中:

public void AddConversion<T, TResult>(Expression<Func<T, object>> propertySelector, Func<object, TResult> converter)
{
    Expression body = propertySelector.Body;
    // 处理值类型转object的装箱转换
    if (body is UnaryExpression unary && unary.NodeType == ExpressionType.Convert)
    {
        body = unary.Operand;
    }
    
    if (body is MemberExpression memberExpr && memberExpr.Member is PropertyInfo propertyInfo)
    {
        AddConversion<TResult>(propertyInfo, converter);
    }
    else
    {
        throw new InvalidOperationException("表达式必须是属性访问");
    }
}

补充说明

  • 若AddConversion是静态方法,只需将重载也改为静态,并调整类的访问权限即可。
  • 编译器会根据传入的属性选择器自动推断泛型参数T,无需手动指定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:23:22