Unity中如何从传入Module构造的IEnumerator获取Container实例引用
在Unity中通过协程迭代器获取所属Container实例的解决方案
问题场景
我正在Unity中开发项目,需要在Module的构造函数里,仅通过传入的IEnumerator类型参数,获取到持有该协程方法的Container类实例,同时必须遵守以下约束:
Module构造函数不得添加其他参数(比如直接传入Container实例)Module构造函数的唯一参数必须为IEnumerator,不能改为Func<>等其他类型- 传入的协程不会被直接调用(比如不使用
StartCoroutine(...)) - 构造函数内的逻辑不能移到单独方法(公共方法或扩展方法都不行)
原始代码示例
class Module { // 构造函数 public Module(IEnumerator _someCoroutine) { // 此处需要直接从_someCoroutine参数获取 // 持有该协程方法引用的Container类实例(而非“typeof(Container)”) } } class Container : MonoBehaviour { void Awake() { Module module = new Module(SomeCoroutine()); } IEnumerator SomeCoroutine() { // 协程逻辑 yield return null; } }
解决方案代码
class Module { public Module(IEnumerator _someCoroutine) { // 通过反射获取迭代器所属的实例引用 var field = _someCoroutine.GetType().GetField("<>4__this", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); Container containerInstance = field?.GetValue(_someCoroutine) as Container; // 现在可以使用containerInstance了 if (containerInstance != null) { // 执行需要的逻辑,比如调用Container的方法、访问成员等 Debug.Log($"成功获取到Container实例:{containerInstance.name}"); } } } class Container : MonoBehaviour { void Awake() { Module module = new Module(SomeCoroutine()); } IEnumerator SomeCoroutine() { yield return null; } }
原理说明
当你在C#中调用实例的迭代器方法(比如SomeCoroutine())时,编译器会生成一个隐藏的迭代器类,这个类会包含一个名为<>4__this的私有字段,用来持有当前的实例引用(也就是调用该方法的Container对象)。通过反射访问这个字段,就能获取到对应的Container实例。
注:这种方式依赖C#编译器的实现细节,在Unity常用的Mono/.NET运行时环境下该字段名是稳定的,但不同编译器版本可能存在变动风险。
内容的提问来源于stack exchange,提问作者user3868427
相关产品推荐
相关产品推荐

