469,621 Members | 1,678 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

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

Why does foreach raise exception when no elements of specified typeexist?

When I do this:
foreach( Button btn in myForm.Controls )

An exception is raised when no buttons exist. I would simply expect
execution to continue after the foreach loop (just as would be the case
with a regular for loop when the second expression is false when the
loop begins).

Is there an explanation for this?
Nov 17 '05 #1
8 1952
Hi,
No, an exception is throw when the first control that is not a Button is
found. if instead of

foreach( Button btn in myForm.Controls )

you write

foreach( Control btn in myForm.Controls )

you do not get that error

use this:
foreach( Button btn in myForm.Controls )
if ( btn is TextBox )
{
}
and take a look into OOP concepts as inheritance.

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Brad Wood" <bradley_.wood_@ndsu_.edu> wrote in message
news:OI**************@TK2MSFTNGP14.phx.gbl...
When I do this:
foreach( Button btn in myForm.Controls )

An exception is raised when no buttons exist. I would simply expect
execution to continue after the foreach loop (just as would be the case
with a regular for loop when the second expression is false when the loop
begins).

Is there an explanation for this?

Nov 17 '05 #2
Another way to code this:

foreach (Control ctl in myForm.Controls)
{
Button btn = ctl as Button;
if (btn != null)
{
...
}
}

Nov 17 '05 #3
Ignacio Machin ( .NET/ C# MVP ) wrote:
Hi,
No, an exception is throw when the first control that is not a Button is
found. if instead of

foreach( Button btn in myForm.Controls )

you write

foreach( Control btn in myForm.Controls )

you do not get that error

use this:
foreach( Button btn in myForm.Controls )
if ( btn is TextBox )
{
}
and take a look into OOP concepts as inheritance.

cheers,


What I didn't understand is the way that the foreach loop works. I
thought it would implicitly only act on objects in the collection that
matched the declared type.
I understand that I could declare my foreach variable as a base Control,
but then I have to query each control's type. I thought the foreach
loop would preclude the extra code necessary on my part.
Nov 17 '05 #4
If you write foreach (Button btn in this.Controls)
it is expanded to code which does an explicit cast of each enumerated
element, so
(just for illustrative purpose)
Button btn = (Button)enumerator.Current;
and this rises exception when the Current Contol is not a Button
Hope this answers your question

"Brad Wood" <bradley_.wood_@ndsu_.edu> wrote in message
news:OR**************@tk2msftngp13.phx.gbl...
Ignacio Machin ( .NET/ C# MVP ) wrote:
Hi,
No, an exception is throw when the first control that is not a Button is
found. if instead of

foreach( Button btn in myForm.Controls )

you write

foreach( Control btn in myForm.Controls )

you do not get that error

use this:
foreach( Button btn in myForm.Controls )
if ( btn is TextBox )
{
}
and take a look into OOP concepts as inheritance.

cheers,


What I didn't understand is the way that the foreach loop works. I
thought it would implicitly only act on objects in the collection that
matched the declared type.
I understand that I could declare my foreach variable as a base Control,
but then I have to query each control's type. I thought the foreach
loop would preclude the extra code necessary on my part.

Nov 17 '05 #5
foreach always iterates through every item in a collection, regardless
of what type you declare the receiving variable to be. For each item in
the collection, it attempts to cast that item to the type of variable
that you've supplied. If the cast fails, the foreach fails.

This is even clearer if you remember, as Lebesgue pointed out, that the
foreach loop just calls GetEnumerator() on the collection you pass it,
and the next item for each loop is just the result of calling
MoveNext() on the collection and then looking at the Current property.
You can "write" a foreach yourself like this:

IEnumerator en = myForm.Controls.GetEnumerator();
while (en.MoveNext())
{
Button btn = (Button)en.Current;
...
}

In theory, this should generate exactly the same code as

foreach (Button btn in myForm.Controls)
{
...
}

and, as you can see, the fact that the Current item is being cast to a
Button is separated from the call that moves to the next item, and,
indeed, the loop will fail on the line

Button btn = (Button)en.Current;

because for some controls en.Current will not be a Button.

Nov 17 '05 #6
foreach loops through every item in a collection, regardless of the
type of variable you use to receive the individual items. As Lebesgue
pointed out, foreach is implemented, under the covers using an
IEnumerator. You can write your own "foreach" loop as follows:

IEnumerator en = myForm.Controls.GetEnumerator();
while (en.MoveNext())
{
Button btn = (Button)en.Current;
...
}

this is exactly equivalent to

foreach (Button btn in myForm.Controls)
{
...
}

As you can see, the "moving to next control" call is completely
separate from the "get current item and cast to Button" call.

Nov 17 '05 #7
Hi,

What I didn't understand is the way that the foreach loop works. I
thought it would implicitly only act on objects in the collection that
matched the declared type.


I suggest you to read a book about C# , will help you understand the core of
the language and will save you a lot of problem down the line
Nov 17 '05 #8
I misunderstood how the foreach loop works. I thought it would make an
implicit type comparison on each object. That would save me from having
to check each base control object's type against my desired type in the
loop.
It's too bad I can't just write a foreach loop with my desired
descendant type and go from there...
Nov 17 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Ed Brandmark | last post: by
11 posts views Thread by Grant Edwards | last post: by
7 posts views Thread by Steven W. Orr | last post: by
29 posts views Thread by Jon Slaughter | last post: by
10 posts views Thread by =?Utf-8?B?YmJn?= | last post: by
reply views Thread by devrayhaan | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.