【问题标题】:C# Trying to make my own List with a static index counterC# 尝试使用静态索引计数器创建自己的列表
【发布时间】:2011-09-19 19:55:51
【问题描述】:

我想创建自己的List,它可以在foreach loop 中工作。除了其他重要的命令之外,List 也有类似 IndexOf (这是我唯一不喜欢 List 的地方,因为它是动态变化的)。我列表中的一个必须跟踪所有索引。以及 AddContainsCountRemove 以及 [] 访问器(不知道怎么做)所以现在 Get 应该可以解决问题。

List 应该被转换为一个名为 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# 似乎非常高级且难以掌握概念。

实体列表的来源

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

}

【问题讨论】:

  • 不好意思问了,为什么?
  • 为什么什么?为什么我要这样做?好吧,从长远来看,它会更加灵活,我认为这就像将引擎藏在引擎盖下的汽车中,因为您知道它会正常运行,您不必担心太多。好吧,再加上它有点重用代码,因为没有这个类,我将为 Npc/Player 提供 2 组索引保持器。嗯,我不知道为什么,但我想解决这个问题,谢谢,如果你知道出了什么问题,请告诉我我是一个新手,正在学习如何在 C# 中做事
  • 如果你的意思是我为什么不使用列表?好吧,List 的索引是动态的.. 我希望它们是静态的.. 总结一下。假设第 500 个索引中的玩家退出.. 500 之后的所有玩家都将被转移并搞砸索引的顺序.. 如果第一个玩家退出, 地狱.. 每个人都搞砸了.. 与 npcs 相同。

标签: list ienumerable icollection enumerator


【解决方案1】:

我不是 100% 确定您需要什么,但您是否查看过 Dictionary 对象?如果您使用通用版本,您可以定义自己的密钥并让它保存您需要的任何项目

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

请阅读您的最后一条评论: 您可以决定不使用列表的索引作为位置,而是使用我提到的字典或仅使用列表,而不是使用索引器(将“搞砸”的数字)检查列表中项目的属性(让列表中的项目拥有自己的“索引”,您可以 100% 控制)

【讨论】:

  • 无法定义我自己的键.. 这就是键必须像普通列表一样增加的点.. 不是移位顺序。还必须实现密钥重用(使用最低的可用密钥)然后再次使用我想要做的所有逻辑将被隐藏起来不会看起来那么混乱。
猜你喜欢
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多