You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 14:46:01