tags:

views:

769

answers:

3

The Errors are in public IEnumerator GetEnumerator() and private sealed class d__0

Could you Gurus help to convert those unreadable/understandable code into something I or compiler understand ones...

Many Many Thanks first...

below is the code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Runtime.CompilerServices;
using System.Diagnostics;

namespace MyNmSpace.Utilities.Data
{
    [Serializable]

public class MyHashList<T> : IList<T>, ICollection<T>, IEnumerable<T>, ICollection, IEnumerable where T: DbObject
{
    // Fields
    protected Dictionary<int, T> _dict;
    protected List<int> _list;
    protected int _lowestId;

    // Methods
    public MyHashList()
    {
        this._lowestId = -2;
    }

    public virtual void Add(T item)
    {
        this.Insert(this.TheList.get_Count(), item);
    }

    public virtual void AddRange(IEnumerable<T> collection)
    {
        foreach (T local in collection)
        {
            this.Add(local);
        }
    }

    public virtual void Clear()
    {
        this.TheDict.Clear();
        this.TheList.Clear();
    }

    public MyHashList<T> Clone()
    {
        MyHashList<T> list = new MyHashList<T>();
        foreach (T local in this)
        {
            list.Add(local);
        }
        return list;
    }

    public virtual bool Contains(Predicate<T> match)
    {
        foreach (T local in this)
        {
            if (match(local))
            {
                return true;
            }
        }
        return false;
    }

    public virtual bool Contains(T item)
    {
        return (bool) (item.Id.get_HasValue() && this.ContainsId(item.Id.Value));
    }

    public virtual bool ContainsId(int id)
    {
        return (bool) ((id > -1) && this.TheDict.ContainsKey(id));
    }

    public virtual void CopyTo(T[] array, int arrayIndex)
    {
        for (int i = arrayIndex; i < (arrayIndex + this.Count); i = (int) (i + 1))
        {
            array[i] = this[i];
        }
    }

    public virtual T[] Filter(Predicate<T> match)
    {
        List<T> list = new List<T>();
        foreach (T local in this)
        {
            if (match(local))
            {
                list.Add(local);
            }
        }
        return list.ToArray();
    }

    public virtual T Find(Predicate<T> match)
    {
        foreach (T local in this)
        {
            if (match(local))
            {
                return local;
            }
        }
        return default(T);
    }

    public virtual T Find(int id)
    {
        if (!this.TheDict.ContainsKey(id))
        {
            return default(T);
        }
        return this.TheDict[id];
    }

    public virtual void ForEach(Action<T> function)
    {
        foreach (T local in this)
        {
            function(local);
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        <GetEnumerator>d__0<T> d__ = new <GetEnumerator>d__0<T>(0);
        d__.<>4__this = (MyHashList<T>) this;
        return d__;
    }

    public virtual int IndexOf(T item)
    {
        if (item.Id.get_HasValue())
        {
            return this.IndexOfId(item.Id.Value);
        }
        return -1;
    }

    public virtual int IndexOfId(int Id)
    {
        return this.TheList.IndexOf(Id);
    }

    public virtual void Insert(int index, T item)
    {
        if (item.Id.get_HasValue())
        {
            int? id = item.Id;
            if (!((id.GetValueOrDefault() < 0) && id.get_HasValue()) || !this.TheDict.ContainsKey(item.Id.Value))
            {
                goto Label_0083;
            }
        }
        item.Id = new int?(this._lowestId);
        this._lowestId = (int) (this._lowestId - 1);
    Label_0083:
        this.TheDict.Add(item.Id.Value, item);
        this.TheList.Insert(index, item.Id.Value);
    }

    public virtual bool Remove(T item)
    {
        return this.RemoveId(item.Id.Value);
    }

    public virtual void RemoveAt(int index)
    {
        this.TheDict.Remove(this.TheList.get_Item(index));
        this.TheList.RemoveAt(index);
    }

    public virtual bool RemoveId(int id)
    {
        if (this.TheDict.ContainsKey(id))
        {
            this.TheDict.Remove(id);
            this.TheList.Remove(id);
            return true;
        }
        return false;
    }

    public virtual void Sort(Comparison<int> compare)
    {
        this.TheList.Sort(compare);
    }

    void ICollection.CopyTo(Array array, int arrayIndex)
    {
        this.CopyTo((T[]) array, arrayIndex);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    // Properties
    public int Count
    {
        get
        {
            return this.TheList.get_Count();
        }
    }

    public T this[int index]
    {
        get
        {
            return this.TheDict[this.TheList.get_Item(index)];
        }
        set
        {
            this.RemoveAt(index);
            this.Insert(index, value);
        }
    }

    bool ICollection<T>.IsReadOnly
    {
        get
        {
            return false;
        }
    }

    bool ICollection.IsSynchronized
    {
        get
        {
            return false;
        }
    }

    object ICollection.SyncRoot
    {
        get
        {
            return this;
        }
    }

    protected virtual Dictionary<int, T> TheDict
    {
        get
        {
            if (this._dict == null)
            {
                this._dict = new Dictionary<int, T>();
            }
            return this._dict;
        }
    }

    protected virtual List<int> TheList
    {
        get
        {
            if (this._list == null)
            {
                this._list = new List<int>();
            }
            return this._list;
        }
    }

    // Nested Types
    [CompilerGenerated]
    private sealed class <GetEnumerator>d__0 : IEnumerator<T>, IEnumerator, IDisposable
    {
        // Fields
        private int <>1__state;
        private T <>2__current;
        public MyHashList<T> <>4__this;
        public List<int>.Enumerator <>7__wrap2;
        public int <id>5__1;

        // Methods
        [DebuggerHidden]
        public <GetEnumerator>d__0(int <>1__state)
        {
            this.<>1__state = <>1__state;
        }

        private bool MoveNext()
        {
            bool flag;
            try
            {
                switch (this.<>1__state)
                {
                    case 0:
                        this.<>1__state = -1;
                        this.<>7__wrap2 = this.<>4__this.TheList.GetEnumerator();
                        this.<>1__state = 1;
                        goto Label_0083;

                    case 2:
                        this.<>1__state = 1;
                        goto Label_0083;

                    default:
                        goto Label_00A8;
                }
            Label_0044:
                this.<id>5__1 = this.<>7__wrap2.Current;
                this.<>2__current = this.<>4__this.TheDict[this.<id>5__1];
                this.<>1__state = 2;
                return true;
            Label_0083:
                if (this.<>7__wrap2.MoveNext())
                {
                    goto Label_0044;
                }
                this.<>1__state = -1;
                this.<>7__wrap2.Dispose();
            Label_00A8:
                flag = false;
            }
            fault
            {
                ((IDisposable) this).Dispose();
            }
            return flag;
        }

        [DebuggerHidden]
        void IEnumerator.Reset()
        {
            throw new NotSupportedException();
        }

        void IDisposable.Dispose()
        {
            switch (this.<>1__state)
            {
                case 1:
                case 2:
                    break;

                default:
                    return;
                    try
                    {
                    }
                    finally
                    {
                        this.<>1__state = -1;
                        this.<>7__wrap2.Dispose();
                    }
                    break;
            }
        }

        // Properties
        T IEnumerator<T>.Current
        {
            [DebuggerHidden]
            get
            {
                return this.<>2__current;
            }
        }

        object IEnumerator.Current
        {
            [DebuggerHidden]
            get
            {
                return this.<>2__current;
            }
        }
    }
}
+1  A: 

I can at least help you understand why this is produced. It's probably because the original code used an iterator block, which is translated into a confusing mix of labels and gotos that make up a state machine. It's one of the things that Reflector cannot properly translate back to the original code.

RCIX
You are right, I do think so; but is there any way to understand or this is a impossible task to convert such code to something understandable?
Tigerbug
Or do you have a such routine/Class which can also perform a similar fuction? Many thanks
Tigerbug
Cause this is a very common usage database hashlist class, cheers
Tigerbug
A: 

This is the code that using yield return to return an IEnumerable generates. The compiler generates a state machine that keeps track of where you are, and this is what the non-C# syntax is. It also uses similar code to implement automatic properties and delegate closures as well. Reflector currently can't work out what the yield statements were from the state machine, so it does the best it can with gotos and labels.

thecoop
Thanks, I know it better now. Do you think if you have to look through this code and try to get a working class out, would that be a possible task or totally no way to achive? Very hard for me at least.
Tigerbug
If you replaced the invalid names for variables then it would *technically* work...
RCIX
A: 

I found a such artical in net Reflector forum, may help everyone to understand this problem, and hope next version of .net Reflector can solve this issue:

Author: odalet PostPosted: Thu Oct 23, 2008 9:12 pm The Post is an answer to question - return new GetEnumerator>d__0(0) { <>4__this = this }

In fact, from .NET 2.0, some language constructs are just syntactic sugar and lead to IL generation when compiled. These constructs include the yield statement among others (anonymous delegates and lambdas, anonymous types, linq, ...)

I think the code you've seen is the generated code for a yield. Each time you build a quick IEnumerable implementation by writing a yield return..., behind the scene (at compile time) a complete enumerator class is built. Because it is directly generated in IL (well, I suppose so), the variable and method names don't have to respect C# naming restrictions.

Starting this post, I said it may be a "missing" functionality. It would be great if we could turn on an option asking Reflector to check for the C# correctness of the statements, and if not correct, to generate C# compliant (or VB compliant) names (should not be too difficult: usually these variables and methods are private or internal, and any obfuscator knows how to do this...).

In the same area, some problems can arise with non C# keywords or constructs. Usually switch statements don't compile back correctly (because if some goto that jump too far away for the C# compiler. And we can find some strange blocks in try/catch/finally: a faultblock can appear... This is valid in IL, but not in C#

Tigerbug