используя .NET Reflector на C # DLL получите ниже нечитаемый код, как мне исправить этот класс? - PullRequest
0 голосов
/ 07 октября 2009

Ошибки находятся в общедоступном IEnumerator GetEnumerator () и закрытом закрытом классе d__0

Не могли бы вы, Гуру, помочь преобразовать этот нечитаемый / понятный код в нечто, понятное мне или компилятору ...

Сначала большое спасибо ...

ниже код

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;
            }
        }
    }
}

Ответы [ 4 ]

2 голосов
/ 07 октября 2009

Я могу, по крайней мере, помочь вам понять, почему это происходит. Вероятно, потому, что в исходном коде использовался блок итератора, который переводится в запутанную смесь меток и переходов, составляющих конечный автомат. Это одна из вещей, которую Reflector не может правильно перевести обратно в исходный код.

0 голосов
/ 10 января 2013

вы можете попробовать заменить на это:

public IEnumerator<T> GetEnumerator()
{
        foreach (var e in this.list)
        {
            yield return e;
        }
}
0 голосов
/ 07 октября 2009

Я нашел такой художественный в сетевом форуме Reflector, может помочь всем понять эту проблему, и надеюсь, что следующая версия .net Reflector может решить эту проблему:

Автор: odalet PostPosted: четверг, 23, 2008 9:12 вечера Сообщение является ответом на вопрос - верните новый GetEnumerator> d__0 (0) {<> 4__this = this}

Фактически, из .NET 2.0 некоторые языковые конструкции являются просто синтаксическим сахаром и приводят к генерации IL при компиляции. Эти конструкции включают в себя оператор yield среди прочих (анонимные делегаты и лямбды, анонимные типы, linq, ...)

Я думаю, что код, который вы видели, является сгенерированным кодом для выхода. Каждый раз, когда вы создаете быструю реализацию IEnumerable, записывая возвращение yield ..., за сценой (во время компиляции) создается полный класс перечислителя. Поскольку он генерируется непосредственно в IL (ну, я так полагаю), имена переменных и методов не должны соответствовать ограничениям именования C #.

Начиная этот пост, я сказал, что это может быть «отсутствующая» функциональность. Было бы замечательно, если бы мы могли включить опцию, запрашивающую Reflector, проверять правильность операторов на C #, а если нет, генерировать имена, совместимые с C # (или VB) (не должно быть слишком сложно: обычно эти переменные и методы) являются частными или внутренними, и любой обфускатор знает, как это сделать ...).

В той же области могут возникнуть некоторые проблемы с не ключевыми словами или конструкциями C #. Обычно операторы switch не компилируются обратно правильно (потому что если некоторые goto прыгают слишком далеко для компилятора C #. И мы можем найти некоторые странные блоки в try / catch / finally: может появиться блок ошибок ... Это действительно в IL , но не в C #

0 голосов
/ 07 октября 2009

Это код, который использует yield return для генерации IEnumerable. Компилятор генерирует конечный автомат, который отслеживает, где вы находитесь, и это синтаксис не-C #. Он также использует аналогичный код для реализации автоматических свойств и делегирования замыканий. В настоящее время Reflector не может определить, какие операторы yield были получены от конечного автомата, поэтому он работает лучше всего с gotos и label.

...