您的位置:首页 > 移动开发 > Unity3D

ILSpy反编译Unity协程

2017-03-30 01:18 821 查看

问题分析

直接用ILSpy或类似工具反编译出的C#脚本里协程(Coroutine)和编写时明显不同:

无参数协程示例:

private IEnumerator startCt_result()
{
ScGame.<startCt_result>c__IteratorE <startCt_result>c__IteratorE = new ScGame.<startCt_result>c__IteratorE();
<startCt_result>c__IteratorE.<>f__this = this;
return <startCt_result>c__IteratorE;
}
带参数协程示例:

private IEnumerator FreeRun(float holdTime)
{
NinjaMovementScript.<FreeRun>c__IteratorD <FreeRun>c__IteratorD = new NinjaMovementScript.<FreeRun>c__IteratorD();
<FreeRun>c__IteratorD.holdTime = holdTime;
<FreeRun>c__IteratorD.<$>holdTime = holdTime;
<FreeRun>c__IteratorD.<>f__this = this;
return <FreeRun>c__IteratorD;
}
可以看出编译器将C#编译为IL时候将yield return XXX这样的语法糖展开成为一个自动生成的类,默认设置下这个类并不能直接在ILSpy里看到,在ILSpy里选择View -> Options,取消勾选Decompile enumerators后就能看到这个自动生成的类。

示例代码如下(对应带参数的协程示例):

[CompilerGenerated]
private sealed class <FreeRun>c__IteratorD : IEnumerator, IDisposable, IEnumerator<object>
{
internal float holdTime;
internal int $PC;
internal object $current;
internal float <$>holdTime; //这个holdTime应该是检测WaitForSeconds是否完成用的
internal NinjaMovementScript <>f__this;

object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return this.$current;
}
}

object IEnumerator.Current
{
[DebuggerHidden]
get
{
return this.$current;
}
}

public bool MoveNext()
{
uint num = (uint)this.$PC;
this.$PC = -1;
switch (num)
{
case 0u:
this.$current = new WaitForSeconds(this.holdTime);
this.$PC = 1;
return true;
case 1u:
this.<>f__this.Freezz = false;
this.$PC = -1;
break;
}
return false;
}

[DebuggerHidden]
public void Dispose()
{
this.$PC = -1;
}

[DebuggerHidden]
public void Reset()
{
throw new NotSupportedException();
}
}
显然这是一个将代码块yield return语句展开后生成的迭代器状态机类,yield return是C# 2提供的语法糖,避免了C# 1时代手动编写状态机的过程。因此我们可以轻易的分析出yield return语句应该是:

IEnumerator FreeRun(float holdTime)
{
yield return new WaitForSeconds(this.holdTime);
this.Freezz = false; //脚本NinjaMovementScript的字段
}


参考资料

1.《C# in Depth》3rd Edition。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity 协程 ILSpy 反编译 c#