You need to enable JavaScript to run this app. C#中能否创建可接收method group作为参数的泛型方法?
优惠活动
大模型
产品
解决方案
定价
更多

C#中能否创建可接收method group作为参数的泛型方法?

方案可行性结论与实现

可行性结论

你期望的效果完全可以实现。C# 没有原生可直接声明为参数的MethodGroup类型(MethodGroup是编译器层面的概念),改用表达式树即可实现强类型、无方法执行、仅提取方法元数据的需求,比你原来传字符串的方案更安全,重构时不会因为方法名修改遗漏替换字符串而出错。

实现代码

using System.Linq.Expressions;
using System.Reflection;
using FakeItEasy;
using FakeItEasy.Configuration;

public static class FakeExtensions
{
    public static IAnyCallConfigurationWithReturnTypeSpecified<ReturnType> ReturnForMethod<SUT, ReturnType>(
        this Fake<SUT> fake,
        Expression<Func<SUT, object>> methodSelector,
        ReturnType returnObj)
    {
        string methodName = ResolveMethodName(methodSelector);
        var call = fake.AnyCall()
            .WithReturnType<ReturnType>()
            .Where(callContext => callContext.Method.Name == methodName);

        call.Returns(returnObj);
        return call;
    }

    private static string ResolveMethodName<T>(Expression<Func<T, object>> selector)
    {
        // 解析方法选择表达式的语法树,提取方法名
        if (selector.Body is UnaryExpression unaryExpr 
            && unaryExpr.Operand is MethodCallExpression methodCallExpr
            && methodCallExpr.Object is ConstantExpression constantExpr
            && constantExpr.Value is MethodInfo methodInfo)
        {
            return methodInfo.Name;
        }

        throw new ArgumentException("请传入符合规范的方法选择表达式,格式为 s => s.目标方法名", nameof(selector));
    }
}

调用方式

和你期望的形式完全一致,编译期会自动校验方法是否存在:

new Fake<IDummyFactory>().ReturnForMethod(s => s.Create, testStr);

补充说明

  • 该实现仅解析表达式树的语法结构,完全不会执行目标方法,运行开销和nameof几乎一致
  • 如果需要匹配带重载的方法,可以扩展解析逻辑,从表达式树中提取方法参数类型信息,在匹配规则中增加参数校验即可
  • 所有校验逻辑在编译期生效,不存在传错方法名的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 08:18:02