471,354 Members | 1,130 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,354 software developers and data experts.

VS2005/c#2.0: enum and user control problems

I'm using VS2005 beta 2.

(1) It looks like "foreach" is looking for an IEnumerable only, and not an
IEnumerator.
That means that class I use in the interation has to have GetEnumerator(),
rather than supporting the IEnumerator protocol (incl. automatically created
generator class using "yield return".) I can define GetEnumerator(), but
this forces me into one implementation (or an ugly class with state that
swiches and calls a sub-enumerator), rather than calling the IEnumerator
directly.
So I can't do:
public IEnumerator listForwards() { yield return 1; yield return 2; }
public IEnumerator listBackwards() { yield return 2; yield return 1; }
foreach ( int i in listForwards()) { ... }
but I'm forced to write:
public IEnumerator GetEnumerator() { return listForwards(); }
to get things to work, boxing me in to what GE() returns.
It's already bad enough that generator functions in c# are restricted to
being enumerators, I hope things aren't even more screwy.
Googling shows that the fomer should work in 2.0. (I know there's an issue
about not having a default GetEnumerator() in the new collections, but
that's a different issue.)

(2) I cannot create an empty winform user control, add it to the toolbox,
and drop it on a form -- either nothing happens, or an error is generated
about not being able to load the control (without other explanation.) The
same exersize works fine (obviously) in VS2003.
Please let me know if I'm misunderstanding things here or have done
something silly, or if the release bits will solve these problems...

thanks,
m
Nov 28 '05 #1
6 1329

"Mike" <vi********@yahoo.com> wrote in message
news:Od**************@TK2MSFTNGP14.phx.gbl...
(1) It looks like "foreach" is looking for an IEnumerable only, and not an
IEnumerator.
That means that class I use in the interation has to have GetEnumerator(),

....

Not really -- this works for me, but maybe I'm missing the point -- just
type the return as IEnumerable:
public class RaceGrid
{
int[] _rg = new int[] { 1, 2 };
public IEnumerable ListForward()
{
for(int i = 0; i < _rg.Length; ++i)
yield return _rg[i];
}
}

Client-side code looks like:
RaceGrid rg = new RaceGrid();
foreach(int i in rg.ListForward())
{
Console.WriteLine(i);
}

--
Mickey Williams
C# MVP, MCT, Author
http://www.servergeek.com/blogs/mickey
Nov 29 '05 #2
Mike wrote:
I'm using VS2005 beta 2.

(1) It looks like "foreach" is looking for an IEnumerable only, and not an
IEnumerator.
That means that class I use in the interation has to have GetEnumerator(),


Simply add a GetEnumerator() method that returns this:

public class SomeClass<T> : IEnumerator<T>, IEnumerable<T>
{
....

public IEnumerator<T> GetEnumerator()
{
return this;
}

....
}

(this assumes you're using .NET 2.0 and that the class implements
IEnumerator<T>, if not, just remove <T>).

Of course, doing it this way as opposed to constructing a new enumerator
class wrapping your object means that only one enumerator can be used at
any given time against such an object.

--
Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:la***@vkarlsen.no
PGP KeyID: 0x2A42A1C2
Nov 30 '05 #3

"Lasse Vågsæther Karlsen" <la***@vkarlsen.no> wrote in message
news:OH**************@TK2MSFTNGP09.phx.gbl...
Mike wrote:
I'm using VS2005 beta 2.

(1) It looks like "foreach" is looking for an IEnumerable only, and not
an IEnumerator.
That means that class I use in the interation has to have
GetEnumerator(),
Simply add a GetEnumerator() method that returns this:

public class SomeClass<T> : IEnumerator<T>, IEnumerable<T>
{
....

public IEnumerator<T> GetEnumerator()
{
return this;
}


The key word there is "simply". The whole issue is that your class may have
multiple enumerators.
(For example, c.EnumInOrder(), c.EnumSorted(), c.EnumWithFilter("foo"),
etc.)
C# does not have Java-style non-static inner classes (which is fine with me
in general) so this forces the use of some other pattern (such as a class
which "switches" or several sub-classes) to get differrent enumerators - all
of which requires more code than necessary. (If it weren't for the fact the
just returning IEnumerable from the generator works, whether it make sense
or not...)


....
}

(this assumes you're using .NET 2.0 and that the class implements
IEnumerator<T>, if not, just remove <T>).

Of course, doing it this way as opposed to constructing a new enumerator
class wrapping your object means that only one enumerator can be used at
any given time against such an object.

--
Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:la***@vkarlsen.no
PGP KeyID: 0x2A42A1C2

Nov 30 '05 #4

"Mickey Williams [C# MVP]" <myfirstnameatservergeekdotcom> wrote in message
news:OE****************@TK2MSFTNGP09.phx.gbl...

"Mike" <vi********@yahoo.com> wrote in message
news:Od**************@TK2MSFTNGP14.phx.gbl...
(1) It looks like "foreach" is looking for an IEnumerable only, and not
an IEnumerator.
That means that class I use in the interation has to have
GetEnumerator(), ...

Not really -- this works for me, but maybe I'm missing the point -- just
type the return as IEnumerable:


Yes, this seems to work. The point is -- this is, if not a bug, at least a
wart.
The protocol that is encapsulated by IEnumerator (Current, MoveNext()...) is
all that is required for "foreach" to work.
It would makes sense to use IEnumerable as backup if the target for
"foreach" did not support IEnumerator, but it should not require it.

m
public class RaceGrid
{
int[] _rg = new int[] { 1, 2 };
public IEnumerable ListForward()
{
for(int i = 0; i < _rg.Length; ++i)
yield return _rg[i];
}
}

Client-side code looks like:
RaceGrid rg = new RaceGrid();
foreach(int i in rg.ListForward())
{
Console.WriteLine(i);
}

--
Mickey Williams
C# MVP, MCT, Author
http://www.servergeek.com/blogs/mickey

Nov 30 '05 #5
"Mike" <vi********@yahoo.com> wrote in message
news:Og**************@TK2MSFTNGP14.phx.gbl...
The key word there is "simply". The whole issue is that your class may
have multiple enumerators.
(For example, c.EnumInOrder(), c.EnumSorted(), c.EnumWithFilter("foo"),
etc.)
C# does not have Java-style non-static inner classes (which is fine with
me in general) so this forces the use of some other pattern (such as a
class which "switches" or several sub-classes) to get differrent
enumerators - all of which requires more code than necessary. (If it
weren't for the fact the just returning IEnumerable from the generator
works, whether it make sense or not...)


This is what C#2.0 custom iterators are for -- requires a bare minimum of
code.

class ManyIterators
{
private string[] values;

public IEnumerable<string> GetValues()
{
return this.values;
}

public IEnumerable<string> GetValuesInReverse()
{
for (int i=values.Length-1; i>=0; --i)
{
yield return this.values[i];
}
}

public IEnumerable<string> GetValuesAndAppend(string tail)
{
foreach (string s in this.values)
{
yield return s + tail;
}
}
}
ManyIterators iter;
foreach (string s in iter.GetValues())
{
//...
}
foreach (string s in iter.GetValuesInReverse())
{
//...
}

etc
Dec 4 '05 #6

"Ted Miller" <te*@millerzone.net> wrote in message
news:11*************@corp.supernews.com...
"Mike" <vi********@yahoo.com> wrote in message
news:Og**************@TK2MSFTNGP14.phx.gbl...
The key word there is "simply". The whole issue is that your class may
have multiple enumerators.
(For example, c.EnumInOrder(), c.EnumSorted(), c.EnumWithFilter("foo"),
etc.)
C# does not have Java-style non-static inner classes (which is fine with
me in general) so this forces the use of some other pattern (such as a
class which "switches" or several sub-classes) to get differrent
enumerators - all of which requires more code than necessary. (If it
weren't for the fact the just returning IEnumerable from the generator
works, whether it make sense or not...)
This is what C#2.0 custom iterators are for -- requires a bare minimum of
code.


Yes, I know.

I was pointing out that IEnumerator should be the required signature for
"foreach" to work - not IEnumerable.
The fact that the auto-generated code for the yeilding function in effect
generates an IEnumerable implementation that points to itself is what makes
this work, but is hardly necessary.

m

class ManyIterators
{
private string[] values;

public IEnumerable<string> GetValues()
{
return this.values;
}

public IEnumerable<string> GetValuesInReverse()
{
for (int i=values.Length-1; i>=0; --i)
{
yield return this.values[i];
}
}

public IEnumerable<string> GetValuesAndAppend(string tail)
{
foreach (string s in this.values)
{
yield return s + tail;
}
}
}
ManyIterators iter;
foreach (string s in iter.GetValues())
{
//...
}
foreach (string s in iter.GetValuesInReverse())
{
//...
}

etc

Dec 5 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

20 posts views Thread by Glenn Venzke | last post: by
21 posts views Thread by Andreas Huber | last post: by
18 posts views Thread by Visual Systems AB \(Martin Arvidsson\) | last post: by
7 posts views Thread by Dino Buljubasic | last post: by
1 post views Thread by John Olbert | last post: by
reply views Thread by SenthilVel | last post: by
34 posts views Thread by Steven Nagy | last post: by
reply views Thread by XIAOLAOHU | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.