C#如何定义可配合MakeGenericMethod使用的泛型Lambda以避免单独声明方法
解决方案
你要的内联泛型逻辑、无需在类级别单独定义方法的需求,可以通过以下两种方案实现:
方案1:使用泛型本地函数(推荐,C# 7.0及以上版本支持)
C# 7.0 引入的本地函数支持泛型定义,你可以直接在 CallingFunc 内部定义仅当前方法可用的泛型函数,完全符合「内联」的要求,反射调用逻辑和你原来的写法几乎一致:
public void CallingFunc() { var someType = typeof(whatever); // 运行时通过反射获取的类型变量 // 泛型本地函数,仅在CallingFunc内部可见,不需要在类级别单独定义 void SomeFunc<Tf>() { // 这里写你原来要实现的针对Tf的类型安全逻辑 Console.WriteLine($"当前泛型参数类型:{typeof(Tf).FullName}"); } // 获取泛型方法定义:随便传入一个占位泛型参数拿到委托,再提取泛型方法定义即可 Delegate tempDel = (Action)SomeFunc<object>; var genericMethodDef = tempDel.Method.GetGenericMethodDefinition(); // 后续逻辑和你原来的写法完全一致 var concreteMethod = genericMethodDef.MakeGenericMethod(someType); concreteMethod.Invoke(this, null); }
该方案的优势是逻辑完全内联在你需要的位置,不需要额外定义类级别的成员,代码可读性最高。
方案2:通用泛型辅助类(兼容低版本C#)
如果你使用的C#版本不支持本地函数,可以先定义一个全局通用的泛型执行辅助类,这个类只需要定义一次,所有同类场景都可以复用,不需要每次单独定义业务泛型方法:
// 全局通用辅助类,仅需定义一次 public static class GenericRunner { public static void Run<T>(Action logic) { logic(); } // 按需扩展带返回值的重载 public static TResult Run<T, TResult>(Func<TResult> logic) { return logic(); } }
使用时直接把你的业务逻辑以内联Lambda的形式传入即可:
public void CallingFunc() { var someType = typeof(whatever); // 运行时获取的类型变量 // 获取泛型执行方法的定义 var genericRunMethod = typeof(GenericRunner).GetMethod(nameof(GenericRunner.Run), new[] { typeof(Action) }); var concreteRunMethod = genericRunMethod.MakeGenericMethod(someType); // 直接传入内联Lambda作为执行逻辑 concreteRunMethod.Invoke(null, new object[] { new Action(() => { // 这里写你针对T的类型安全逻辑 Console.WriteLine($"当前泛型参数类型:{typeof(whatever).FullName}"); }) }); }
内容的提问来源于stack exchange,提问作者Evengard
相关产品推荐
相关产品推荐

