2016-08-03 13 views
1

호기심 때문에 프로젝트 코드를 디 컴파일하려고했습니다. 어셈블리 .dll 파일을 가져 와서 ILSpy를 사용하여 디 컴파일했습니다. IEnumerator<> 메소드를 제외하고 올바르게 작동하는 것 같습니다. IEnumerators Decompiling

IEnumerator sP() 
{ 
     for (int i = 0; i < maxEnemies; i++) 
     { 
      var p = Porczaks[Random.Range(0, Porczaks.Length)]; 
      Instantiate(p, new Vector3(Random.Range(245, 360), 16.8f, Random.Range(292, 366)), Quaternion.Euler(0f, Random.Range(0f, 359f), 0f)); 
      yield return new WaitForEndOfFrame(); 
     } 
} 

은 ... 예를 들어이로 디코딩되고 :

[DebuggerHidden] 
private IEnumerator sP() 
{ 
    WaveManager.<sP>c__Iterator7 <sP>c__Iterator = new WaveManager.<sP>c__Iterator7(); 
    <sP>c__Iterator.<>f__this = this; 
    return <sP>c__Iterator; 
} 

는에 정확하게 그 IEnumerator 디 컴파일 방법이 있습니까?

편집 : 내가 dotPeek의 디 컴파일러를 사용하여 동일한 어셈블리를 디 컴파일하고,이 방법은 더 많은 코드를 만들었습니다. 난 아직 확실하지 않다하지만 변수는 그물에 같은 이름을 가질 수있는 경우 :

// Method sP with token 060000AB 
[/*Attribute with token 0C000051*/DebuggerHidden] 
private IEnumerator sP() 
{ 
    WaveManager.\u003CsP\u003Ec__Iterator7 sPCIterator7 = new WaveManager.\u003CsP\u003Ec__Iterator7(); 
    sPCIterator7.\u003C\u003Ef__this = this; 
    return (IEnumerator) sPCIterator7; 
} 

// Type <sP>c__Iterator7 with token 02000031 
[/*Attribute with token 0C000026*/CompilerGenerated] 
private sealed class \u003CsP\u003Ec__Iterator7 : IEnumerator<object>, IEnumerator, IDisposable 
{ 
    // Field <i>__0 with token 040000C7 
    internal int \u003Ci\u003E__0; 
    // Field <p>__1 with token 040000C8 
    internal GameObject \u003Cp\u003E__1; 
    // Field $PC with token 040000C9 
    internal int \u0024PC; 
    // Field $current with token 040000CA 
    internal object \u0024current; 
    // Field <>f__this with token 040000CB 
    internal WaveManager \u003C\u003Ef__this; 

    // Property System.Collections.Generic.IEnumerator<object>.Current with token 17000017 
    object IEnumerator<object>.System\u002ECollections\u002EGeneric\u002EIEnumerator\u003Cobject\u003E\u002ECurrent 
    { 
     // Method System.Collections.Generic.IEnumerator<object>.get_Current with token 060000EA 
     [/*Attribute with token 0C00006E*/DebuggerHidden] get 
     { 
     return this.\u0024current; 
     } 
    } 

    // Property System.Collections.IEnumerator.Current with token 17000018 
    object IEnumerator.Current 
    { 
     // Method System.Collections.IEnumerator.get_Current with token 060000EB 
     [/*Attribute with token 0C00006F*/DebuggerHidden] get 
     { 
     return this.\u0024current; 
     } 
    } 

    // Method .ctor with token 060000E9 
    public \u003CsP\u003Ec__Iterator7() 
    { 
     base.\u002Ector(); 
    } 

    // Method MoveNext with token 060000EC 
    public bool MoveNext() 
    { 
     uint num = (uint) this.\u0024PC; 
     this.\u0024PC = -1; 
     switch (num) 
     { 
     case 0: 
      this.\u003Ci\u003E__0 = 0; 
      break; 
     case 1: 
      this.\u003Ci\u003E__0 = this.\u003Ci\u003E__0 + 1; 
      break; 
     default: 
      return false; 
     } 
     if (this.\u003Ci\u003E__0 < this.\u003C\u003Ef__this.maxEnemies) 
     { 
     this.\u003Cp\u003E__1 = this.\u003C\u003Ef__this.Porczaks[UnityEngine.Random.Range(0, this.\u003C\u003Ef__this.Porczaks.Length)]; 
     UnityEngine.Object.Instantiate((UnityEngine.Object) this.\u003Cp\u003E__1, new Vector3((float) UnityEngine.Random.Range(245, 360), 16.8f, (float) UnityEngine.Random.Range(292, 366)), Quaternion.Euler(0.0f, UnityEngine.Random.Range(0.0f, 359f), 0.0f)); 
     this.\u0024current = (object) new WaitForEndOfFrame(); 
     this.\u0024PC = 1; 
     return true; 
     } 
     this.\u0024PC = -1; 
     goto default; 
    } 

    // Method Dispose with token 060000ED 
    [/*Attribute with token 0C000070*/DebuggerHidden] 
    public void Dispose() 
    { 
     this.\u0024PC = -1; 
    } 

    // Method Reset with token 060000EE 
    [/*Attribute with token 0C000071*/DebuggerHidden] 
    public void Reset() 
    { 
     throw new NotSupportedException(); 
    } 
} 

는 dotPeek가 제대로 <>을 처리하지 않은 것 같다,하지만이 코드는 어떤 가치가있다?

+0

실제로 컴파일러에서 생성되는 것처럼 보입니다. – Enigmativity

+0

JetBrains dotPeek이 더 나은 작업을 수행한다고합니다. – Enigmativity

+0

나는 dotPeek를 체크해 봤고 토큰이 코드에서 보이지 않을 때 ILSpy에서 코드와 거의 비슷하게 보이지만 실제로는 혼란스럽게된다. 첫 번째 게시물에 코드를 게시했습니다. 어떤 의미가 있습니까? ' __ + @! #'의 이름을 정상적인 것으로 변경 한 경우 작동합니까? – Reynevan

답변

1

컴파일러가 yield return 문을 대체하기 위해 생성하는 상용구 코드가 실제로 표시됩니다. 그리고 네, 실제로 그것은 상태 기계입니다.

일반적으로 디 컴파일러는 컴파일러에서 생성 된 상용구 코드를 인식하고 올바른 C# 문으로 대체 할 수 있어야합니다. 그러나 이러한 인식은 패턴 매칭 (pattern matching)에 의해 수행된다. 즉, 상용구 코드는 매우 특정한 방식으로 구성 될 것으로 예상된다. 컴파일러가 동일한 코드를 생성하지만 구조가 다른 경우 (예 : 컴파일러 업그레이드, 최적화 등) 디 컴파일러가 패턴을 일치시키지 않고 yield 문을 인식하지 못합니다.

당신이해야 할 일은 디 컴파일러 팀에게 버그 보고서를 제출하여 문제가 수정되고 수동으로 물건의 이름을 변경할 필요가 없도록하는 것입니다. 그 어셈블리에서 JustDecompile을 해봤습니까? 그것도 실패합니까? 그렇다면 Telerik 포럼에 게시 할 수 있습니다.

참고로, 어떤 컴파일러를 사용 했습니까?