467,074 Members | 849 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,074 developers. It's quick & easy.

Implementing a Enumerator interface

Hi ,
I am learning C# and now am stuck with a simple prorgam.Tried googling
but didn't get an answer :(. The following program gives me three
compilation errors.Can anyone enlighten me? Thanks.

using System;
using System.Collections.Generic;
using System.Text;

namespace Collections
{
public class Tokens : IEnumerable<String>
{
private String[] elements;

Tokens(String source, char[] delimiters)
{
elements = source.Split(delimiters);
}

~Tokens()
{
}

public IEnumerator<StringGetEnumerator()
{
return new TokenEnumerator(this);
}

private class TokenEnumerator:IEnumerator<String>
{
private Int32 pos = -1;
private Tokens t;

public TokenEnumerator(Tokens tok)
{
t = tok;
}

public Boolean MoveNext()
{
if (pos < t.elements.Length - 1)
{
pos++;
return true;
}
else
{
return false;
}
}

public void Reset()
{
pos = -1;
}

public String Current
{
get { return t.elements[pos]; }
}
}

public static void Main()
{
Tokens f = new Tokens("This is my first C# program", new
char[] { ' ', '#' });
foreach (String s in f)
{
Console.WriteLine(s);
}
}
}
}

Error 1 'Collections.Tokens.TokenEnumerator' does not implement
interface member 'System.IDisposable.Dispose()'
Error 2 'Collections.Tokens.TokenEnumerator' does not implement
interface member 'System.Collections.IEnumerator.Current'.
'Collections.Tokens.TokenEnumerator.Current' is either static, not
public, or has the wrong return type

Error 3 'Collections.Tokens' does not implement interface member
'System.Collections.IEnumerable.GetEnumerator()'.
'Collections.Tokens.GetEnumerator()' is either static, not public, or
has the wrong return type.

Sep 3 '06 #1
  • viewed: 8660
Share:
3 Replies
Senthil wrote:
Hi ,
I am learning C# and now am stuck with a simple prorgam.Tried googling
but didn't get an answer :(. The following program gives me three
compilation errors.Can anyone enlighten me? Thanks.
First, since you're using C# 2.0, it's much (much, much!) easier to use the
new interator syntax that's built into the language (look up 'yield return'
in the C# language reference). See additional comments about the errors
you're getting inline, below.
>
using System;
Add:

using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Collections
{
public class Tokens : IEnumerable<String>
{
private String[] elements;

Tokens(String source, char[] delimiters)
{
elements = source.Split(delimiters);
}

~Tokens()
{
}

public IEnumerator<StringGetEnumerator()
{
return new TokenEnumerator(this);
}
You also need

IEnumerator IEnumerable.GetEnumerator()
{
return new TokenEnumerator(this);
}

to supply an implementation for IEnumerable.GetEnumerator, since
IEnumerable<Tderives from IEnumerable.
>
private class TokenEnumerator:IEnumerator<String>
{
private Int32 pos = -1;
private Tokens t;

public TokenEnumerator(Tokens tok)
{
t = tok;
}

public Boolean MoveNext()
{
if (pos < t.elements.Length - 1)
{
pos++;
return true;
}
else
{
return false;
}
}

public void Reset()
{
pos = -1;
}

public String Current
{
get { return t.elements[pos]; }
}
This supplies IEnumerator<string>.Current, but you also need

object IEnumerator.Current
{
get {re turn t.elements[pos]; }
}

to supply an implementation of IEnumerator.Current since IEnumerator<sT>
derives from IEnumerator.
You also need

void IDisposable.Dispose()
{
}

since IEnumerator<Tderives from IDisposable.
}

public static void Main()
{
Tokens f = new Tokens("This is my first C# program", new
char[] { ' ', '#' });
foreach (String s in f)
{
Console.WriteLine(s);
}
}
}
}

Sep 3 '06 #2
Senthil wrote:
I am learning C#
I see you are using C# 2.0.
and now am stuck with a simple prorgam.Tried googling
but didn't get an answer :(. The following program gives me three
compilation errors.Can anyone enlighten me? Thanks.
I'll go through the errors first, before I deal with the code.
Error 1 'Collections.Tokens.TokenEnumerator' does not implement
interface member 'System.IDisposable.Dispose()'
This refers to the fact that IEnumerator<Tdescends from IDisposable,
so to implement IEnumerator<T>, you also need to implement IDisposable.
Error 2 'Collections.Tokens.TokenEnumerator' does not implement
interface member 'System.Collections.IEnumerator.Current'.
'Collections.Tokens.TokenEnumerator.Current' is either static, not
public, or has the wrong return type
This refers to the fact that IEnumerator<Talso descends from
IEnumerator, and the IEnumerator.Current property is of type 'object',
not 'string'. You'd need an explicit implementation, like this:

object IEnumerator.Current
{
get { return Current; } // uses the Current of type 'string'
}
Error 3 'Collections.Tokens' does not implement interface member
'System.Collections.IEnumerable.GetEnumerator()'.
'Collections.Tokens.GetEnumerator()' is either static, not public, or
has the wrong return type.
This is similar to the error for Current. Again, you need an explicit
implementation:

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

Note that calling methods like this, inside the type, never resolves to
an explicit interface method implementation. So, this won't recurse
indefinitely.
using System;
using System.Collections.Generic;
using System.Text;
[...]
~Tokens()
{
}
This is a finalizer. It is *highly* unlikely that your type needs a
finalizer, and its presence will make your class a lot less efficient
than it can be.

Finally, I'd like to point you to iterators, a feature of C# 2.0 which
make implementing enumerators a lot easier (ignoring the fact that you
could just return 'elements.GetEnumerator()'). Your program could be
written with iterators in the following manner:

---8<---
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Collections
{
public class Tokens : IEnumerable<String>
{
private String[] elements;

Tokens(String source, char[] delimiters)
{
elements = source.Split(delimiters);
}

~Tokens()
{
}

public IEnumerator<StringGetEnumerator()
{
for (int i = 0; i < elements.Length; ++i)
yield return elements[i];
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public static void Main()
{
Tokens f = new Tokens("This is my first C# program", new
char[] { ' ', '#' });
foreach (String s in f)
{
Console.WriteLine(s);
}
}
}
}
--->8---

-- Barry

--
http://barrkel.blogspot.com/
Sep 3 '06 #3

Barry Kelly wrote:
Senthil wrote:
I am learning C#

I see you are using C# 2.0.
and now am stuck with a simple prorgam.Tried googling
but didn't get an answer :(. The following program gives me three
compilation errors.Can anyone enlighten me? Thanks.

I'll go through the errors first, before I deal with the code.
Error 1 'Collections.Tokens.TokenEnumerator' does not implement
interface member 'System.IDisposable.Dispose()'

This refers to the fact that IEnumerator<Tdescends from IDisposable,
so to implement IEnumerator<T>, you also need to implement IDisposable.
Error 2 'Collections.Tokens.TokenEnumerator' does not implement
interface member 'System.Collections.IEnumerator.Current'.
'Collections.Tokens.TokenEnumerator.Current' is either static, not
public, or has the wrong return type

This refers to the fact that IEnumerator<Talso descends from
IEnumerator, and the IEnumerator.Current property is of type 'object',
not 'string'. You'd need an explicit implementation, like this:

object IEnumerator.Current
{
get { return Current; } // uses the Current of type 'string'
}
Error 3 'Collections.Tokens' does not implement interface member
'System.Collections.IEnumerable.GetEnumerator()'.
'Collections.Tokens.GetEnumerator()' is either static, not public, or
has the wrong return type.

This is similar to the error for Current. Again, you need an explicit
implementation:

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

Note that calling methods like this, inside the type, never resolves to
an explicit interface method implementation. So, this won't recurse
indefinitely.
using System;
using System.Collections.Generic;
using System.Text;
[...]
~Tokens()
{
}
This is a finalizer. It is *highly* unlikely that your type needs a
finalizer, and its presence will make your class a lot less efficient
than it can be.

Finally, I'd like to point you to iterators, a feature of C# 2.0 which
make implementing enumerators a lot easier (ignoring the fact that you
could just return 'elements.GetEnumerator()'). Your program could be
written with iterators in the following manner:

---8<---
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Collections
{
public class Tokens : IEnumerable<String>
{
private String[] elements;

Tokens(String source, char[] delimiters)
{
elements = source.Split(delimiters);
}

~Tokens()
{
}

public IEnumerator<StringGetEnumerator()
{
for (int i = 0; i < elements.Length; ++i)
yield return elements[i];
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public static void Main()
{
Tokens f = new Tokens("This is my first C# program", new
char[] { ' ', '#' });
foreach (String s in f)
{
Console.WriteLine(s);
}
}
}
}
--->8---

-- Barry
Thanks for your replies folks!!!
>
--
http://barrkel.blogspot.com/
Sep 3 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Martyn Lawson | last post: by
2 posts views Thread by Gordon Rundle | last post: by
3 posts views Thread by Adam Clauss | last post: by
7 posts views Thread by csharpula csharp | last post: by
5 posts views Thread by Nikolay Belyh | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.