FOREACH does not determine Object type? 
Author Message
 FOREACH does not determine Object type?

Hi,

I use a custom control on a standard form. In fact, there are some of them.
When the state of the control(I won't go in to what the control does)
changes, it changes the state of all the others too. To achieve this, I
FOREACH through the parent.controls collection from within the control.

I assumed that this:

FOREACH(MyControl c in this.parent.controls)

would return only objects from the type MyControl but is does not. In my
case, first It did return only my objects (they came first in de collection
i guess) but the next one was a commandbutton and FOREACH returned an
exeption stating that it cannot perform the cast....

Now I simply use

FOREACH(Control c in this.parent.controls)

and try/catch the expection trown when i try to cast myself. This works but
to me it looks ehh well strange.

Wy would to first code not work? In VB6 this works so one would expect this
to work in C# in the same way (FOREACH came from VB I believe).

Greetings,

Roland



Mon, 27 Jun 2005 14:43:03 GMT  
 FOREACH does not determine Object type?

foreach will iterate through the entire controls collection, which is
exactly what you are asking it to do.  I am not familiar with the VB6
implementation but I suspect the problem you are having is caused primarily
by C#'s stronger type system.

To get around this, within the foreach loop you can test the type:

  if (c is MyControl)

This should be significantly faster than the overhead incurred by catch
blocks.

--Bob


Quote:
> Hi,

> I use a custom control on a standard form. In fact, there are some of
them.
> When the state of the control(I won't go in to what the control does)
> changes, it changes the state of all the others too. To achieve this, I
> FOREACH through the parent.controls collection from within the control.

> I assumed that this:

> FOREACH(MyControl c in this.parent.controls)

> would return only objects from the type MyControl but is does not. In my
> case, first It did return only my objects (they came first in de
collection
> i guess) but the next one was a commandbutton and FOREACH returned an
> exeption stating that it cannot perform the cast....

> Now I simply use

> FOREACH(Control c in this.parent.controls)

> and try/catch the expection trown when i try to cast myself. This works
but
> to me it looks ehh well strange.

> Wy would to first code not work? In VB6 this works so one would expect
this
> to work in C# in the same way (FOREACH came from VB I believe).

> Greetings,

> Roland



Mon, 27 Jun 2005 15:26:54 GMT  
 FOREACH does not determine Object type?

Quote:

> Wy would to first code not work? In VB6 this works so one would expect this
> to work in C# in the same way (FOREACH came from VB I believe).

I personally think the C# way of doing it is the natural way - not
having used VB much at all. The key, of course, is to read the
specification, which says (amongst other things):

<quote>
A foreach statement of the form:

foreach (ElementType element in collection) statement  

corresponds to one of two possible expansions:

* 2 If the collection expression is of a type that implements the
collection pattern (as defined above), the expansion of the foreach
statement is:

Enumerator enumerator = (collection).GetEnumerator();  
try {  
   while (enumerator.MoveNext()) {  
      ElementType element = (ElementType)enumerator.Current;  
      statement;  
   }  

Quote:
}  

finally {  
   IDisposable disposable = enumerator as System.IDisposable;  
   if (disposable != null) disposable.Dispose();  

Quote:
}  

[...]

    * 3 Otherwise; the collection expression is of a type that
implements System.IEnumerable, and the expansion of the foreach
statement is:

IEnumerator enumerator =  
((System.IEnumerable)(collection)).GetEnumerator();  
try {  
   while (enumerator.MoveNext()) {  
      ElementType element = (ElementType)enumerator.Current;  
      statement;  
   }  

Quote:
}  

finally {  
   IDisposable disposable = enumerator as System.IDisposable;  
   if (disposable != null) disposable.Dispose();  
Quote:
}  

</quote>

Given that, it makes perfect sense that you'd get an exception if you
try to tell foreach that each element in the collection is a Foo an one
turns out not to be.

--
Jon Skeet

If replying to the group, please do not mail me at the same time



Mon, 27 Jun 2005 17:14:31 GMT  
 FOREACH does not determine Object type?
Well I also thought when I started in C# that "foreach X x in y" would have
the mathematical sense i.e. "for each member of y that is of type X". So
what's natural to you seemed unnatural to me. Like, why would I strongly
type x (make it something other than object) if I wanted other kinds of
things to be iterated over?

I suppose one advantage with the existing implementation is that if you are
expecting everything in the collection to be an X and something happens not
to be then you get an exception rather than it being silently passed over.

VB is (was?) nicer I think as it had "For Each x in y Where
boolean-condition" -- OK it's just a syntactic nicety but brings out the
sense more dontchathink.


Quote:

> > Wy would to first code not work? In VB6 this works so one would expect
this
> > to work in C# in the same way (FOREACH came from VB I believe).

> I personally think the C# way of doing it is the natural way - not
> having used VB much at all.

> --
> Jon Skeet

> If replying to the group, please do not mail me at the same time



Mon, 27 Jun 2005 20:49:00 GMT  
 FOREACH does not determine Object type?

Quote:

> Well I also thought when I started in C# that "foreach X x in y" would have
> the mathematical sense i.e. "for each member of y that is of type X". So
> what's natural to you seemed unnatural to me. Like, why would I strongly
> type x (make it something other than object) if I wanted other kinds of
> things to be iterated over?

> I suppose one advantage with the existing implementation is that if you are
> expecting everything in the collection to be an X and something happens not
> to be then you get an exception rather than it being silently passed over.

Exactly. I'd always expected foreach to be just a shortcut for iterating
and casting.

Quote:
> VB is (was?) nicer I think as it had "For Each x in y Where
> boolean-condition" -- OK it's just a syntactic nicety but brings out the
> sense more dontchathink.

That would certainly make it clear that filtering was occuring.

--
Jon Skeet

If replying to the group, please do not mail me at the same time



Mon, 27 Jun 2005 21:08:03 GMT  
 FOREACH does not determine Object type?


Quote:
> Hi,

> I use a custom control on a standard form. In fact, there are some of
them.
> When the state of the control(I won't go in to what the control does)
> changes, it changes the state of all the others too. To achieve this, I
> FOREACH through the parent.controls collection from within the control.

> I assumed that this:

> FOREACH(MyControl c in this.parent.controls)

> would return only objects from the type MyControl but is does not. In my
> case, first It did return only my objects (they came first in de
collection
> i guess) but the next one was a commandbutton and FOREACH returned an
> exeption stating that it cannot perform the cast....

There is a nice tutorial on "foreach" coming with VS.NET

Vlastik



Mon, 27 Jun 2005 22:08:09 GMT  
 FOREACH does not determine Object type?


Quote:
> Well I also thought when I started in C# that "foreach X x in y" would
have
> the mathematical sense i.e. "for each member of y that is of type X". So
> what's natural to you seemed unnatural to me. Like, why would I strongly
> type x (make it something other than object) if I wanted other kinds of
> things to be iterated over?

You can make your enumarator return Object type, so in this way you will
take away strong type checking.\

 Vlastik



Mon, 27 Jun 2005 22:10:26 GMT  
 FOREACH does not determine Object type?


Quote:

> > Well I also thought when I started in C# that "foreach X x in y" would
have
> > the mathematical sense i.e. "for each member of y that is of type X". So
> > what's natural to you seemed unnatural to me. Like, why would I strongly
> > type x (make it something other than object) if I wanted other kinds of
> > things to be iterated over?

> > I suppose one advantage with the existing implementation is that if you
are
> > expecting everything in the collection to be an X and something happens
not
> > to be then you get an exception rather than it being silently passed
over.

> Exactly. I'd always expected foreach to be just a shortcut for iterating
> and casting.

This "feature by design" is well documented in MS online documentation .

 Vlastik



Mon, 27 Jun 2005 22:11:25 GMT  
 FOREACH does not determine Object type?

Quote:


> > Hi,

> > I use a custom control on a standard form. In fact, there are some of
> them.
> > When the state of the control(I won't go in to what the control does)
> > changes, it changes the state of all the others too. To achieve this, I
> > FOREACH through the parent.controls collection from within the control.

> > I assumed that this:

> > FOREACH(MyControl c in this.parent.controls)

> > would return only objects from the type MyControl but is does not. In my
> > case, first It did return only my objects (they came first in de
> collection
> > i guess) but the next one was a commandbutton and FOREACH returned an
> > exeption stating that it cannot perform the cast....

> > Now I simply use

> > FOREACH(Control c in this.parent.controls)

> > and try/catch the expection trown when i try to cast myself. This works
> but
> > to me it looks ehh well strange.

> > Wy would to first code not work? In VB6 this works so one would expect
> this
> > to work in C# in the same way (FOREACH came from VB I believe).

> > Greetings,

> > Roland



Quote:
> foreach will iterate through the entire controls collection, which is
> exactly what you are asking it to do.  I am not familiar with the VB6
> implementation but I suspect the problem you are having is caused
primarily
> by C#'s stronger type system.

> To get around this, within the foreach loop you can test the type:

>   if (c is MyControl)

> This should be significantly faster than the overhead incurred by catch
> blocks.

> --Bob

** Message chronology repeared **

Hi,

I implemented your suggestion and naturally it works fine. At least it looks
like better coding not having to try/catch 'cause this can't go wrong.

But still I believe that with saying FOREACH(MyControl c in
this.parent.controls) should let me iteratie through objects of the type
MyControl in the controls collection. I will ask Bill to make it so  :-)

Thanx,

Roland



Tue, 28 Jun 2005 13:51:32 GMT  
 FOREACH does not determine Object type?


Quote:


> > > Hi,

> > > I use a custom control on a standard form. In fact, there are some of
> > them.
> > > When the state of the control(I won't go in to what the control does)
> > > changes, it changes the state of all the others too. To achieve this,
I
> > > FOREACH through the parent.controls collection from within the
control.

> > > I assumed that this:

> > > FOREACH(MyControl c in this.parent.controls)

> > > would return only objects from the type MyControl but is does not. In
my
> > > case, first It did return only my objects (they came first in de
> > collection
> > > i guess) but the next one was a commandbutton and FOREACH returned an
> > > exeption stating that it cannot perform the cast....

> > > Now I simply use

> > > FOREACH(Control c in this.parent.controls)

> > > and try/catch the expection trown when i try to cast myself. This
works
> > but
> > > to me it looks ehh well strange.

> > > Wy would to first code not work? In VB6 this works so one would expect
> > this
> > > to work in C# in the same way (FOREACH came from VB I believe).

> > > Greetings,

> > > Roland



> > foreach will iterate through the entire controls collection, which is
> > exactly what you are asking it to do.  I am not familiar with the VB6
> > implementation but I suspect the problem you are having is caused
> primarily
> > by C#'s stronger type system.

> > To get around this, within the foreach loop you can test the type:

> >   if (c is MyControl)

> > This should be significantly faster than the overhead incurred by catch
> > blocks.

> > --Bob

> ** Message chronology repeared **

> Hi,

> I implemented your suggestion and naturally it works fine. At least it
looks
> like better coding not having to try/catch 'cause this can't go wrong.

> But still I believe that with saying FOREACH(MyControl c in
> this.parent.controls) should let me iteratie through objects of the type
> MyControl in the controls collection. I will ask Bill to make it so  :-)

> Thanx,

> Roland

Build your own Eumerator (see Collections tutorial in VS.NET) and it will do
EXACTLY what you want..

 Vlastik

- Show quoted text -



Wed, 29 Jun 2005 01:07:47 GMT  
 FOREACH does not determine Object type?

--
Visit the C# product team at http://www.gotdotnet.com/team/csharp

This posting is provided "AS IS" with no warranties, and confers no rights.

Quote:
> Hi,

> I implemented your suggestion and naturally it works fine. At least it
looks
> like better coding not having to try/catch 'cause this can't go wrong.

> But still I believe that with saying FOREACH(MyControl c in
> this.parent.controls) should let me iteratie through objects of the type
> MyControl in the controls collection. I will ask Bill to make it so  :-)

This column shows a techique you can use to make this a bit easier.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncs...
l/csharp01212002.asp



Wed, 29 Jun 2005 06:33:03 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. Object type checking problem in foreach

2. Showing Call Stack and Determine which object is not valid LARGE CHUNK OF CODE

3. Multiple types using foreach - Is this possible?

4. Type Conversion and foreach

5. Type Casting between Base and Derived Type (Serialization of objects with Type members)

6. accessing object properties in a foreach loop

7. Type Info, Parameter Info Not working while mouse is over an object or method

8. Foreach will not work...

9. Object type cannot be converted to target type

10. ATL data type for VB Object data Type

11. Why can't overload type cast to base type (object)

12. HOWTO set the property type of an ATL object to be another ATL object

 

 
Powered by phpBB® Forum Software