开发者

C# How to create a Generic List Collection with a IEnumerator

Hello I am having syntax issues here completely confused on how to properly do this.

My Custom List Source: (with errors) on GetEnmerator() and lots of Warnings

Error and Warnings are:

Error 1 'EntityListEnumerator' does not implement interface member 'System.Collections.IEnumerator.Current'. 'EntityListEnumerator.Current' cannot implement 'System.Collections.IEnumerator.Current' because it does not have the matching return type of 'object'.

Warning 2 'EntityList.Add(T)' hides inherited member 'System.Collections.Generic.List.Add(T)'. Use the new keyword if hiding was intended.

Warning 3 'EntityList.this[int]' hides inherited member 'System.Collections.Generic.List.this[int]'. Use the new keyword if hiding was intended.

Warning 4 'EntityList.Remove(T)' hides inherited member 'System.Collections.Generic.List.Remove(T)'. Use the new keyword if hiding was intended.

Warning 5 'EntityList.IndexOf(T)' hides inherited member 'System.Collections.Generic.List.IndexOf(T)'. Use the new keyword if hiding was intended.

Warning 6 'EntityList.Contains(T)' hides inherited member 'System.Collections.Generic.List.Contains(T)'. Use the new keyword if hiding was intended.

Warning 7 'EntityList.Count' hides inherited member 'System.Collections.Generic.List.Count'. Use the new keyword if hiding was intended.

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

    public EntityList(int capacity) {
        entities = new T[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();
     开发者_如何学C       Add(entity, curIndex);
        } else {
            entities[curIndex] = entity;
            entity.setIndex(index);
            indicies.Add(curIndex);
            increaseIndex();
        }
    }

    public T this[int index]
    {
        get
        {
            return entities[index];
        }
        set
        {
            entities[index] = value;
        }
    }

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

    public Entity Remove(int index)
    {
        Object temp = entities[index];
        entities[index] = null;
        indicies.Remove(index);
        decreaseIndex();
        return (Entity)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();
        }
    }
}

Here is my EntityListEnumerator Source with errors everywhere m mostly some boxing conversation with my real Type to Generic T type

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

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

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

    public virtual T 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(T); //reset current object
        curIndex = -1;
    }

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

How do I fix that error and get rid of those warnings properly. Thanks


You need implement property object Current for IEnumerator:

class EntityListEnumerator<T> : IEnumerator<T> where T : Entity
{
    //....
    object IEnumerator.Current
    {
        get { return Current; }
    }
    //....
}

Also, since your list class inherits List<> you cannot override the methods of List<> since they are not virtual. You may implement your own class that implements ICollection<>. I have created a code snippet for this that you may use:

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>ICollection class</Title>
            <Author>Torbjörn Hansson</Author>
            <Description>Implement a generic ICollection class.</Description>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
            <Shortcut>collection</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>name</ID>
                    <ToolTip>The name of the class</ToolTip>
                    <Default>MyCollection</Default>
                </Literal>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>The type for the ICollection</ToolTip>
                    <Default>string</Default>
                </Literal>
            </Declarations>
            <Code Language="CSharp">
                <![CDATA[
    public class $name$ : ICollection<$type$>
    {
        public $name$()
        {
            this.items = new List<$type$>();
        }

        public $name$(IEnumerable<$type$> collection)
        {
            this.items = new List<$type$>(collection);
        }

        // inner collection
        private List<$type$> items;

        public void Add($type$ item)
        {
            this.items.Add(item);
        }

        public void Clear()
        {
            this.items.Clear();
        }

        public bool Contains($type$ item)
        {
            return this.items.Contains(item);
        }

        public void CopyTo($type$[] array, int arrayIndex)
        {
            this.items.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return this.items.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove($type$ item)
        {
            return this.items.Remove(item);
        }

        public IEnumerator<$type$> GetEnumerator()
        {
            return this.items.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.items.GetEnumerator();
        }
    }
        ]]>

            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

Or just change you EntityList<> class to implement IList<> instead of List<>.


Simply derive from Collection<T> and override the methods whose behaivior you want to change. There's absolutely no need to reimplement all the members you did.

In addition, you should take a look at the yield keyword which allows you to easily create own IEnumerator types.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜