C# 尝试使用静态索引计数器创建我自己的列表
我想制作自己的 List
,它能够在 foreach 循环
中工作。 List
还有其他重要命令,例如 IndexOf(这是我唯一不喜欢 List 的地方,因为它是动态变化的)。我的列表中的那个必须跟踪所有索引。以及添加
、包含
、计数
、删除
以及[]
> 访问器(不知道如何做到这一点),所以现在 Get
应该可以解决问题。
该列表应转换为名为 Entity 的基类,由于其相似性,该基类在其他两个类 Npc / Player 之间共享。
无论如何,我无法控制客户端,我也在对这个服务器进行编码,但是协议规范要求所有玩家跟踪索引,而不像常规列表那样对索引进行任何剧烈的动态更改。
我一直在关注如何制作自己的 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# 的这一部分似乎非常先进且难以掌握概念。
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;
}
}
I want to make my own List
which has the ability to work in foreach loop
. As well as have other important commands a List
has like IndexOf (which is the only thing I don't like about List, since it's dynamically changing). The one in my List has to keep track of all indexes. As well as Add
, Contains
, Count
, Remove
, as well as []
accessors (no idea how to do this) so for now Get
should do the trick.
The List should be casted to a base class called Entity which is shared in between two other Classes Npc / Player for it's similarities.
Anyways I have no control over the client I'm coding this server too, but the protocol specifition requires all players to keep track of indexes without doing any drastic dynamic changes regular List does to index.
I been following a tutorial how to make my own Collections
I got down to 3 errors which I cannot solve.
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
Also i'd like to ask am i doing this right? or something looks dodgy.
Thanks for the help I appreciate it.. this part of C# seems extremely advanced and hard to grasp concept.
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();
}
}
}
Source to 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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不是 100% 确定你需要什么,但是你看过 Dictionary 对象吗?如果您使用通用版本
http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
只需阅读您的最后评论:
您可以决定不使用列表的索引来定位位置,而是使用我提到的字典或仅使用列表,而不是使用索引器(会“搞砸”的数字)检查列表中项目的属性(让列表中的项目拥有自己 100% 控制的“索引”)
I'm not 100% sure what you need, but did you look at the Dictionary object? You can define your own key and have it hold whatever item you need if you use the generic version
http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
Just read your last comment:
You could decide not to use the List's index for position but either use the Dictionary i mentioned or just use a List, but instead of using the indexer (the number that will 'screw up') checking a property on the items in the list (have your items in the list hold its own 'index' that you control 100%)