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

如何移除ExpressionCache类的泛型参数以简化调用?

无泛型参数的表达式编译缓存优化实现

你可以通过将ExpressionCache重构为非泛型静态类,结合泛型方法自动推断类型参数的方式,实现无需显式指定泛型参数的简化调用。核心思路是用Delegate作为缓存值的基类型,兼容所有TSource->TDest的委托类型,再通过泛型方法自动识别具体类型。

优化后的ExpressionCache实现

public static class ExpressionCache
{
    // 用Delegate兼容所有类型的映射委托,键为源类型+目标类型的组合
    private static readonly ConcurrentDictionary<(Type SourceType, Type DestType), Delegate> _mapCache = new();

    // 泛型方法自动推断TSource和TDest,无需调用时显式声明
    public static Func<TSource, TDest> Compile<TSource, TDest>(Expression<Func<TSource, TDest>> map)
    {
        var key = (typeof(TSource), typeof(TDest));
        
        // 尝试从缓存获取并转换为具体委托类型
        if (_mapCache.TryGetValue(key, out var cachedDelegate) && cachedDelegate is Func<TSource, TDest> cachedFunc)
        {
            return cachedFunc;
        }

        // 编译表达式并写入缓存
        var compiledFunc = map.Compile();
        _mapCache[key] = compiledFunc;
        return compiledFunc;
    }
}

简化调用方式

现在你可以直接使用目标语法调用,无需指定泛型参数:

var source = _context.Product.Find(productId);
var dto = ExpressionCache.Compile(Maps.ProductMap)(source);

如果保留MapBuilder,修改后的方法依然可以正常工作:

public static class MapBuilder
{
    public static TDest ToInstance<TSource, TDest>(TSource source, Expression<Func<TSource, TDest>> map)
    {
        return ExpressionCache.Compile(map)(source);
    }
}

// 原有使用方式保持不变
var dto = MapBuilder.ToInstance(source, Maps.ProductMap);

优化说明

  1. 类型自动推断:泛型方法Compile<TSource, TDest>会通过传入的Expression<Func<TSource, TDest>>自动识别源类型和目标类型,无需调用时显式声明。
  2. 缓存兼容性:用Delegate作为缓存值的基类型,可存储任意类型的映射委托,取出时再转换为具体的Func<TSource, TDest>,保证类型安全。
  3. 线程安全:保留ConcurrentDictionary确保多线程环境下的缓存操作安全,避免重复编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:05:34