Reputation: 1274
So I'm trying to port a java Bag class over to C#. I know I've done it wrong here, because a test of this code in a foreach statement produces only the first two added items, but this is not my primary question.
The compiler throws a CS0102 when I try to add an indexer to the Bag class, complaining that Bag<Item>
already contains a definition for Item
. But I can create a method public Item Get(int i)
, which does the very same thing just fine. Why is this happening and how can I create an indexer for this class?
Edit The exact error is: Bag.cs(15,15): Error CS0102: The type Algorithms4e.ch1.Bag<Item>' already contains a definition for
Item' (CS0102)
Just as a side note, I know the Bag class is not supposed to use an indexer, but it's the principle of the thing; I should be able to add an indexer to any class right?
I'm running Mono C# compiler version 3.2.8.0 under Ubuntu 14.04.2 LTS, if that helps at all.
Please let me know if y'all need any more information, or if I'm posting this is the right place to begin with. I'd be happy to update the question.
public class Bag<Item> : IEnumerable<Item> {
private int N; // number of elements in bag
private Node<Item> first; // beginning of bag
// helper linked list class
private class Node<T> {
public T item;
public Node<T> next;
}
/**
* Initializes an empty bag.
*/
public Bag() {
first = null;
N = 0;
}
/**
* Is this bag empty?
* @return true if this bag is empty; false otherwise
*/
public bool isEmpty() {
return first == null;
}
/**
* Returns the number of items in this bag.
* @return the number of items in this bag
*/
public int size() {
return N;
}
/**
* Adds the item to this bag.
* @param item the item to add to this bag
*/
public void Add(Item item) {
Node<Item> oldfirst = first;
first = new Node<Item>();
first.item = item;
first.next = oldfirst;
N++;
}
public Item Get(int i)
{
return ((ListIterator<Item>)GetEnumerator ())[i];
}
public Item this[int i]
{
get {
return ((ListIterator<Item>)GetEnumerator ())[i];
}
}
/**
* Returns an iterator that iterates over the items in the bag in arbitrary order.
* @return an iterator that iterates over the items in the bag in arbitrary order
*/
public IEnumerator<Item> GetEnumerator() {
return new ListIterator<Item>(first);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
// an iterator, doesn't implement remove() since it's optional
private class ListIterator<T> : IEnumerator<T> {
private Node<T> current;
private Node<T> first;
public ListIterator(Node<T> first) {
this.first = first;
current = first;
}
public T GetEnumerator() {
if (!MoveNext ())
throw new Exception ("No such element");
T item = current.item;
//current = current.next;
return item;
}
public T this[int index]
{
get {
Node<T> temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.item;
}
}
public T Current
{
get { return current.item; }
}
object IEnumerator.Current
{
get { return Current; }
}
public void Dispose()
{
current = null;
}
public void Reset()
{
current = first;
}
public bool MoveNext()
{
bool res = (current != null);
current = current.next;
return (res);
}
}
}
Upvotes: 0
Views: 3832
Reputation: 14846
You're running into this because the default property name for indexers is Item
.
If you had followed the naming guidlines for type parameters and named the type parameter TItem
(or just T
), you wouldn't have run into this issue.
But in case you really need the type parameter to be called Item
, you can change the name of the indexer property using the IndexerName attribute:
public class Bag<Item> : IEnumerable<Item>
{
...
[IndexerName("MyIndexer")]
public Item this[int i]
{
get
{
return ((ListIterator<Item>)GetEnumerator ())[i];
}
}
...
}
Upvotes: 1
Reputation: 1973
I believe this is the problem...
https://msdn.microsoft.com/en-us/library/a82kxee5%28v=vs.90%29.aspx
Upvotes: 1
Reputation: 13589
If you are trying to make it generic why do you have T and Item try making it all T
public class Bag<T> : IEnumerable<T>
Upvotes: 1