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

在F#的IEnumerator中能否使用yield return null?(兼容Unity场景)

F#实现Unity兼容的IEnumerator(替代C# yield)

F#的seq表达式编译后不会生成C#风格的yield状态机代码,它基于自身的序列实现机制,所以用ILSpy看不到yield相关的IL指令,但这不代表F#无法实现Unity协程所需的IEnumerator功能。

正确实现方式

要生成符合Unity协程要求的IEnumerator,可以直接手动实现IEnumerator接口,模拟C#中yield return null的逻辑:

open System.Collections

let MyFunc () =
    let mutable isFirstCall = true
    { new IEnumerator with
        member _.Current = null :> obj
        member _.MoveNext() =
            if isFirstCall then
                isFirstCall <- false
                true
            else
                false
        member _.Reset() =
            isFirstCall <- true }

这段代码的效果和你提供的C#代码完全一致:第一次调用MoveNext返回true(对应yield return null),第二次返回false结束枚举。

复杂协程场景扩展

如果需要多步骤的协程逻辑,通过维护状态变量即可实现:

open System.Collections

let ComplexCoroutine () =
    let mutable step = 0
    { new IEnumerator with
        member _.Current =
            match step with
            | 1 | 2 -> null :> obj // 等待两帧
            | _ -> null
        member _.MoveNext() =
            step <- step + 1
            step <= 3 // 执行3次MoveNext,前两次返回true,第三次结束
        member _.Reset() =
            step <- 0 }

关于你之前写法的说明

你之前的seq { yield null } :?> IEnumerator虽然能得到一个IEnumerator,但它是F#惰性序列的枚举器,和C#的yield状态机实现逻辑不同,且无法通过Reset()方法重启(F#序列枚举器的Reset通常会抛出异常),所以不适合Unity协程的重复调用场景。

内容的提问来源于stack exchange,提问作者Edward Yang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:43:23