2011-06-22 7 views
2

こんにちは私は、これを適切に行う方法を完全に混乱させる構文上の問題を抱えています。C#IEnumeratorを使用して汎用リストコレクションを作成する方法

マイカスタムリスト出典:GetEnmerator()と警告の多くに

エラーや警告がある(エラーのある):「インターフェイスメンバを実装していません

エラー1 'EntityListEnumerator' System.Collections.IEnumerator 。現在'。 'EntityListEnumerator.Current'は 'System.Collections.IEnumerator.Current'を実装できません。これは、一致する戻り値の型が 'object'ではないためです。
警告2 'EntityList.Add(T)は継承メンバ' System.Collections.Generic.List.Add(T) 'を非表示にします。隠れが意図されていた場合は、新しいキーワードを使用してください。
警告3 'EntityList.this [int]'は、継承メンバー 'System.Collections.Generic.List.this [int]'を非表示にします。隠れが意図されていた場合は、新しいキーワードを使用してください。
警告4 'EntityList.Remove(T)'は、継承メンバー 'System.Collections.Generic.List.Remove(T)'を非表示にします。隠れが意図されていた場合は、新しいキーワードを使用してください。
警告5 'EntityList.IndexOf(T)'は、継承メンバー 'System.Collections.Generic.List.IndexOf(T)'を非表示にします。隠れが意図されていた場合は、新しいキーワードを使用してください。
警告6 'EntityList.Contains(T)'は、継承メンバー 'System.Collections.Generic.List.Contains(T)'を非表示にします。隠れが意図されていた場合は、新しいキーワードを使用してください。
警告7 'EntityList.Count'は、継承メンバー 'System.Collections.Generic.List.Count'を非表示にします。隠れが意図されていた場合は、新しいキーワードを使用してください。ここで

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

エラーが発生している私のEntityListEnumeratorソースはどこでも、私はそのエラーを修正しないと、適切にこれらの警告を取り除く方法

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

ジェネリックT型に主に私の本当のタイプといくつかのボクシングの会話をmとします。

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

また、あなたのリストのクラスがリスト<を継承しているので、彼らは仮想ではありませんので、>あなたがリスト<>のメソッドをオーバーライドすることはできません:ありがとう

答えて

2

あなたがIEnumeratorをのプロパティobject Currentを実装する必要があります。 ICollection <>を実装する独自のクラスを実装することができます。

<?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> 

それとも、IListの<>代わりの一覧<>を実装することができEntityList <>クラスを変更する:私はあなたが使用することができ、このためのコードスニペットを作成しました。

+0

私はIListの代わりにICollectionを使う必要があると思ったが、残っているインターフェースメンバーを実装することはできなかった。そのコードスニペットはどのようなフォーマットですか.. C#ファイル形式のようには見えませんが、私は以下のコードを想定しています。ドル記号= < >、ああ、私はEntityListと$ type $をEntityで置き換えたと思いますか? – SSpoke

+0

@SSpokeこのスニペットをVS2010にインポートすることができます:Tools/Code Snippets Manager/Import ...これを使用するには、単に 'collection'とintellisenseと入力するだけでこのコードスニペットを挿入することをお勧めします。私はあなたがコピーすることができますスケルトンクラスを挿入:http://pastebin.com/EMyYFC4A –

+0

これはGoogleのこのようなものを見つけることはできませんコレクションの非常に素晴らしく簡単な実装ですすべてのお手伝いをありがとう。 – SSpoke

0

単にコレクション<T>から派生し、変更したいbehaiviorのメソッドをオーバーライドします。あなたがしたすべてのメンバーを再実装する必要は全くありません。

さらに、yieldキーワードを参照すると、独自のIEnumeratorタイプを簡単に作成できます。

関連する問題