泛型方法调用场景下如何对泛型类型做校验并传递给其他泛型方法
实现方案
编译期泛型约束为静态检查,仅通过运行时接口判断无法让编译器识别T满足后续方法的约束,可通过以下三种方案实现需求:
1. 动态调用(最小改动)
通过dynamic绕过编译期检查,运行时类型匹配即可正常执行:
void HandleStandards<T>(..builder..) where T: class, IEntity { if (typeof(IIdentifiable).IsAssignableFrom(typeof(T))) { HandleIdentifiable((dynamic)builder); } if (typeof(ITrackable).IsAssignableFrom(typeof(T))) { HandleTrackable((dynamic)builder); } }
适合内部逻辑可控的场景,缺点是编译期不会校验类型合法性,类型不匹配时会触发运行时异常。
2. 反射调用(更高可控性)
通过反射构造对应约束的泛型方法后执行,可自定义校验逻辑避免运行时异常:
void HandleStandards<T>(..builder..) where T: class, IEntity { var type = GetType(); // 静态方法可替换为typeof(你当前的类名) if (typeof(IIdentifiable).IsAssignableFrom(typeof(T))) { var method = type.GetMethod(nameof(HandleIdentifiable), BindingFlags.Instance | BindingFlags.NonPublic) ?.MakeGenericMethod(typeof(T)); method?.Invoke(this, new object[] { builder }); } if (typeof(ITrackable).IsAssignableFrom(typeof(T))) { var method = type.GetMethod(nameof(HandleTrackable), BindingFlags.Instance | BindingFlags.NonPublic) ?.MakeGenericMethod(typeof(T)); method?.Invoke(this, new object[] { builder }); } }
注意根据方法的实际访问修饰符、是否为静态方法调整BindingFlags参数。
3. 静态缓存优化(高性能场景)
如果方法调用频率较高,可利用泛型静态类的特性做缓存,每个T仅执行一次类型判断和方法构造,后续调用性能接近原生调用:
// 缓存委托的泛型静态类,BuilderType替换为你实际的builder参数类型 private static class StandardHandlerCache<T> where T : class, IEntity { public static readonly Action<BuilderType> Handler = BuildHandler(); private static Action<BuilderType> BuildHandler() { var handlerList = new List<Action<BuilderType>>(); var currentType = typeof(你当前的类名); if (typeof(IIdentifiable).IsAssignableFrom(typeof(T))) { var method = currentType.GetMethod(nameof(HandleIdentifiable), BindingFlags.Instance | BindingFlags.NonPublic)! .MakeGenericMethod(typeof(T)); handlerList.Add(builder => method.Invoke(null, new object[] { builder })); } if (typeof(ITrackable).IsAssignableFrom(typeof(T))) { var method = currentType.GetMethod(nameof(HandleTrackable), BindingFlags.Instance | BindingFlags.NonPublic)! .MakeGenericMethod(typeof(T)); handlerList.Add(builder => method.Invoke(null, new object[] { builder })); } return builder => { foreach (var action in handlerList) { action(builder); } }; } } // 改造后的HandleStandards方法 void HandleStandards<T>(BuilderType builder) where T: class, IEntity { StandardHandlerCache<T>.Handler(builder); }
内容的提问来源于stack exchange,提问作者darcane
相关产品推荐
相关产品推荐

