C # Попытка сделать свой собственный список со счетчиком статических индексов - PullRequest
0 голосов
/ 21 июня 2011

Я хочу сделать свой собственный List, который может работать в foreach loop.Как и другие важные команды, у List есть такой же IndexOf (это единственное, что мне не нравится в List, так как он динамически изменяется).Тот, что в моем списке, должен отслеживать все индексы.Как и Add, Contains, Count, Remove, а также [] аксессоры (не знаю, как это сделать), поэтому на данный момент Get должны сделать свое дело.

Список должен быть приведен к базовому классу под названием Entity, который разделяется между двумя другими классами Npc / Player из-за его сходства.

В любом случае я не контролирую клиента, я тоже кодирую этот сервер, носпецификация протокола требует, чтобы все игроки отслеживали индексы, не делая каких-либо радикальных динамических изменений, которые регулярно вносит List в индекс.

Я следовал учебному пособию о том, как сделать свой собственный Collections Я получил 3 ошибки, которые яне может решить.

Argument 3: cannot convert from 'EntityList<T>' to 'EntityList<Entity>'

Cannot apply indexing with [] to an expression of type 'EntityList<Entity>'

The best overloaded method match for 'EntityListEnumerator<T>.EntityListEnumerator(object[], System.Collections.Generic.HashSet<int>, EntityList<Entity>)' has some invalid arguments

Также я хотел бы спросить, правильно ли я это делаю?или что-то выглядит глупо.

Спасибо за помощь, я ценю это ... эта часть C # кажется чрезвычайно продвинутой и трудной для понимания концепции.

Source to EntityList

public class EntityList<T> : ICollection<T> where T : Entity
{
        private const int DEFAULT_CAPACITY = 1600, MIN_VALUE = 1;
        public object[] entities;
        public HashSet<int> indicies = new HashSet<int>();
        public int curIndex = MIN_VALUE;
        public int capacity;

    public EntityList(int capacity) {
        entities = new object[capacity];
        this.capacity = capacity;
    }

    public EntityList() 
    : this(DEFAULT_CAPACITY) {}

public bool Add(T entity)
{
    Add(entity, curIndex);
    return true;
}

    public void Add(T entity, int index) {
        if (entities[curIndex] != null) {
            increaseIndex();
            Add(entity, curIndex);
        } else {
            entities[curIndex] = entity;
            entity.setIndex(index);
            indicies.Add(curIndex);
            increaseIndex();
        }
    }

public T Get(int index)
{
    return (T)entities[index];
}

public void Remove(T entity)
{
    entities[entity.getIndex()] = null;
    indicies.Remove(entity.getIndex());
    decreaseIndex();
}

public T Remove(int index)
{
    Object temp = entities[index];
    entities[index] = null;
    indicies.Remove(index);
    decreaseIndex();
    return (T)temp;
}

IEnumerator IEnumerable.GetEnumerator()
{
    return new EntityListEnumerator<T>(entities, indicies, this);
}

    private void increaseIndex() {
        curIndex++;
        if (curIndex >= capacity) {
            curIndex = MIN_VALUE;
        }
    }

private void decreaseIndex()
{
        curIndex--;
        if (curIndex <= capacity)
            curIndex = MIN_VALUE;
    }

    public int IndexOf(T entity) {
        foreach(int index in indicies) {
            if (entities[index].Equals(entity)) {
                return index;
            }
        }
        return -1;
    }

public bool Contains(T entity)
{
    return IndexOf(entity) > -1;
}

    public int Count {
    get
    {
        return indicies.Count();
    }
    }
}

Источник в EntityListEnumerator

class EntityListEnumerator<E> : IEnumerator<E> where E : Entity
{
    private int[] indicies;
        private object[] entities;
        private EntityList<Entity> entityList;

protected int curIndex; //current index
protected E _current; //current enumerated object in the collection

public EntityListEnumerator(object[] entities, HashSet<int> indicies, EntityList<Entity> entityList)
{
        this.entities = entities;
        this.indicies = indicies.ToArray();
        this.entityList = entityList;
    curIndex = -1;
    }

public virtual E Current
{
    get
    {
        return _current;
    }
}

public virtual bool MoveNext()
{
    //make sure we are within the bounds of the collection
    if (++curIndex >= entityList.Count)
    {
        //if not return false
        return false;
    }
    else
    {
        //if we are, then set the current element
        //to the next object in the collection
        _current = entityList[indicies[curIndex]];
    }
    //return true
    return true;
}

    public void Remove() {
    if (curIndex >= 1)
    {
        entityList.Remove(indicies[curIndex - 1]);
        }
    }

// Reset the enumerator
public virtual void Reset()
{
    _current = default(E); //reset current object
    curIndex = -1;
}

// Dispose method
public virtual void Dispose()
{
    entityList = null;
    _current = default(E);
    curIndex = -1;
}

}

1 Ответ

0 голосов
/ 21 июня 2011

Я не уверен на 100%, что вам нужно, но вы смотрели на объект Dictionary?Вы можете определить свой собственный ключ, и он будет содержать любой элемент, который вам нужен, если вы используете общую версию

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

Просто прочитайте свой последний комментарий: Вы можете решить не использовать индекс Спискадля позиции, но либо используйте упомянутый мной словарь, либо просто используйте список, но вместо того, чтобы использовать индексатор (число, которое «испортит»), проверяют свойство элементов в списке (ваши элементы в списке сохраняют свои собственные'index', который вы контролируете на 100%)

...