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
相关产品推荐
相关产品推荐

