如何编写泛型函数,调用带特定参数类的回调函数?
如何编写泛型函数,实现调用带有特定类的通用函数?
我来帮你搞定这个泛型复用的问题!你当前的代码里有两个逻辑几乎一致的协程方法,只是对应不同的参数子类和回调委托,完全可以通过泛型来简化,避免重复代码。
先看你提供的原始代码:
public class BaseParamsClass { public BaseParamsClass(int pBaseParam = 0) { baseParam = pBaseParam; } public int baseParam; } public class Parent1ParamsClass : BaseParamsClass { public Parent1ParamsClass(int pBaseParam = 0) : base(pBaseParam) { } public int parentParam1; } public class Parent2ParamsClass : BaseParamsClass { public Parent2ParamsClass(int pBaseParam = 0) : base(pBaseParam) { } public int parentParam2; } public delegate void Parent1Callback(Parent1ParamsClass theParams); public delegate void Parent2Callback(Parent2ParamsClass theParams); private IEnumerator CoRFunction1(Parent1Callback parent1Callback) { // 此处演示调用前执行的一些操作 yield return new WaitForSeconds(1); // 现在获取结果(范围0-10,不同结果应触发不同回调) int result = 0; parent1Callback(new Parent1ParamsClass(0)); } private IEnumerator CoRFunction2(Parent2Callback parent2Callback) { // 此处演示调用前执行的一些操作 yield return new WaitForSeconds(1); // 现在获取结果(范围0-10,不同结果应触发不同回调) int result = 0; // 需要一种泛化方式实现下一行代码:parent2Callback(new Parent2ParamsClass(0)); }
解决方案步骤
1. 定义泛型委托
先把原来的两个特定委托替换成一个泛型委托,适配所有BaseParamsClass的子类:
public delegate void GenericCallback<T>(T theParams) where T : BaseParamsClass;
2. 编写泛型协程函数
创建通用的泛型协程,抽取出重复逻辑,同时通过泛型约束确保传入的类型是BaseParamsClass的子类,并且支持带参数的实例化:
private IEnumerator GenericCoRFunction<T>(GenericCallback<T> callback) where T : BaseParamsClass { // 通用前置操作(比如等待) yield return new WaitForSeconds(1); // 模拟获取业务结果 int result = 0; // 创建对应参数类实例并触发回调 var paramsInstance = (T)Activator.CreateInstance(typeof(T), result); callback(paramsInstance); }
这里用
Activator.CreateInstance是因为new()泛型约束只支持无参构造,而你的子类都是带int参数的构造函数,这种方式可以兼容。
3. 调用泛型函数
现在可以用这个泛型函数替代原来的两个协程,调用方式非常灵活:
// 替代原CoRFunction1的调用 StartCoroutine(GenericCoRFunction<Parent1ParamsClass>((params1) => { // 编写Parent1ParamsClass对应的回调逻辑 Debug.Log($"Parent1基础参数:{params1.baseParam},专属参数:{params1.parentParam1}"); })); // 替代原CoRFunction2的调用 StartCoroutine(GenericCoRFunction<Parent2ParamsClass>((params2) => { // 编写Parent2ParamsClass对应的回调逻辑 Debug.Log($"Parent2基础参数:{params2.baseParam},专属参数:{params2.parentParam2}"); }));
可选优化:用工厂方法替代反射
如果想避免反射(Activator.CreateInstance),可以传入一个工厂方法来创建参数实例,效率更高也更可控:
private IEnumerator GenericCoRFunction<T>(GenericCallback<T> callback, Func<int, T> paramsFactory) where T : BaseParamsClass { yield return new WaitForSeconds(1); int result = 0; var paramsInstance = paramsFactory(result); callback(paramsInstance); } // 调用时传入工厂方法 StartCoroutine(GenericCoRFunction<Parent1ParamsClass>((params1) => { Debug.Log($"Parent1基础参数:{params1.baseParam}"); }, (baseParam) => new Parent1ParamsClass(baseParam)));
这样一来,你就不用维护多个重复的协程方法了,所有通用逻辑都集中在泛型函数里,只需要针对不同参数类传入对应的回调和实例化逻辑即可。
内容的提问来源于stack exchange,提问作者Lior Bruder
相关产品推荐
相关产品推荐

