473,788 Members | 2,811 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

foreach considered dangerous?

foreach does implicitly cast every object in the collection to the specified
taget type without warning.
Without generics this behaviour had the advantage of less typing for us
since casting was neccessary in nearly every collection. But with generics I
consider this feature of foreach as dangerous. Casting is now almost always
unwanted.

interface IFoo{}
class Foo:IFoo{}
class FooBar:IFoo{}

IFoo[] fooarray = {new Foo()} ;

foreach (FooBar in fooarray) // oops InvalidCastExce ption
{
}

My proposal is now that foreach should in future emit a compiler warning if
implicit cast would occur.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
Nov 16 '05 #1
13 2000
Cody:

I'm not sure that I follow your argument, but I'd like to understand it
better. The code example that you created would be invalid with or without
generics. I only see an explicit cast in the code (technically, it's
probably from object to FooBar, because the enumerator probably returns
object)
"cody" <no************ ****@gmx.net> wrote in message
news:%2******** ********@tk2msf tngp13.phx.gbl. ..
foreach does implicitly cast every object in the collection to the specified taget type without warning.
Without generics this behaviour had the advantage of less typing for us
since casting was neccessary in nearly every collection. But with generics I consider this feature of foreach as dangerous. Casting is now almost always unwanted.

interface IFoo{}
class Foo:IFoo{}
class FooBar:IFoo{}

IFoo[] fooarray = {new Foo()} ;

foreach (FooBar in fooarray) // oops InvalidCastExce ption
{
}

My proposal is now that foreach should in future emit a compiler warning if implicit cast would occur.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk

Nov 16 '05 #2
> I'm not sure that I follow your argument, but I'd like to understand it
better. The code example that you created would be invalid with or without generics. I only see an explicit cast in the code (technically, it's
probably from object to FooBar, because the enumerator probably returns
object)

Please reread my posting. there is an implicit cast from Foo to Foobar with
will cause an exception.

But see how dangerous foreach is: even if pointed to the problem people do
not see the invalid cast :)

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #3
J.

There's not a variable there, but this compiles and blows up
IFoo[] fooarray = {new Foo()} ;
foreach (FooBar f in fooarray) // oops InvalidCastExce ption

{
}

"J.Marsch" <je****@ctcdeve loper.com> wrote in message
news:OS******** ******@tk2msftn gp13.phx.gbl...
Cody:

I'm not sure that I follow your argument, but I'd like to understand it
better. The code example that you created would be invalid with or without generics. I only see an explicit cast in the code (technically, it's
probably from object to FooBar, because the enumerator probably returns
object)
"cody" <no************ ****@gmx.net> wrote in message
news:%2******** ********@tk2msf tngp13.phx.gbl. ..
foreach does implicitly cast every object in the collection to the specified
taget type without warning.
Without generics this behaviour had the advantage of less typing for us
since casting was neccessary in nearly every collection. But with

generics I
consider this feature of foreach as dangerous. Casting is now almost

always
unwanted.

interface IFoo{}
class Foo:IFoo{}
class FooBar:IFoo{}

IFoo[] fooarray = {new Foo()} ;

foreach (FooBar in fooarray) // oops InvalidCastExce ption
{
}

My proposal is now that foreach should in future emit a compiler warning

if
implicit cast would occur.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk


Nov 16 '05 #4
> There's not a variable there, but this compiles and blows up
IFoo[] fooarray = {new Foo()} ;
foreach (FooBar f in fooarray) // oops InvalidCastExce ption

{
}

Sorry I forgot :)

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #5

"cody" <no************ ****@gmx.net> wrote in message
news:%2******** ********@tk2msf tngp13.phx.gbl. ..
foreach does implicitly cast every object in the collection to the
specified
taget type without warning.
Without generics this behaviour had the advantage of less typing for us
since casting was neccessary in nearly every collection. But with generics
I
consider this feature of foreach as dangerous. Casting is now almost
always
unwanted.

interface IFoo{}
class Foo:IFoo{}
class FooBar:IFoo{}

IFoo[] fooarray = {new Foo()} ;

foreach (FooBar in fooarray) // oops InvalidCastExce ption
{
}

My proposal is now that foreach should in future emit a compiler warning
if
implicit cast would occur.
The problem is that, without generics, you don't have a choice. And, sorry
to say it, assuming that everything will be generic is short sighted. You
will have to deal with collections typed as object for a long time to come.
foreach isn't dangerous in itself, its the developers fault if anything
fails, especially consdiering you defined the type and should be aware that
means a cast. If you have a collection that isn't strongly typed and you are
concerned it may hold incorrect data, you should be using for and as.

Having said that, the compiler should catch you if you use a type that an
IEnumerable<T> cannot cast or convert to. Which, frankly, is the desired
behaviour. Just throwing a warning if an implicit cast *may* happen on a
enumerator typed object is silly when the compiler can tell you that your
generic enumerator *cannot* perform the cast you want when the type is
FooBar but can't tell you that your cast on object will.

There is no reason to break existing behavior here, and a warning is
certainly not warranted. An error is when the type you request doesn't match
T of any IEnumerable<T> that is available, but thats a different matter
entirely.
--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk

Nov 16 '05 #6
Cody, it's a tiny oversight when bringing up such a good point. It really
didn't dawn on me before, but I agree totally, this is potentially quite
ugly problem.
"cody" <pl************ *************@g mx.de> wrote in message
news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
There's not a variable there, but this compiles and blows up
IFoo[] fooarray = {new Foo()} ;
foreach (FooBar f in fooarray) // oops InvalidCastExce ption

{
}

Sorry I forgot :)

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk

Nov 16 '05 #7
> > foreach does implicitly cast every object in the collection to the
specified
taget type without warning.
Without generics this behaviour had the advantage of less typing for us
since casting was neccessary in nearly every collection. But with generics I
consider this feature of foreach as dangerous. Casting is now almost
always
unwanted.

interface IFoo{}
class Foo:IFoo{}
class FooBar:IFoo{}

IFoo[] fooarray = {new Foo()} ;

foreach (FooBar in fooarray) // oops InvalidCastExce ption
{
}

My proposal is now that foreach should in future emit a compiler warning
if
implicit cast would occur.
The problem is that, without generics, you don't have a choice. And, sorry
to say it, assuming that everything will be generic is short sighted.


Tell me one reason why to use collections containing objects.
This should only be used very very rarely and with lots ofconsideration
done.
You
will have to deal with collections typed as object for a long time to come. foreach isn't dangerous in itself, its the developers fault if anything
fails, especially consdiering you defined the type and should be aware that means a cast. If you have a collection that isn't strongly typed and you are concerned it may hold incorrect data, you should be using for and as.
Strictly speaking, there is no such thing like "strongly typed". If a have a
conventional list, it can contain object and all of its descendants.
If I have a list<IFoo> it can contain IFoo and *all* of its implementing
classes.

Maybe we have to invent a new feature will really allows "very strongly
typed" collections, so that exactly one certain type is allowed, but this
cannot be caught by the compiler.
Having said that, the compiler should catch you if you use a type that an
IEnumerable<T> cannot cast or convert to.
As I said the compiler won't complain it an implicit cast from baseclass to
descentant will take place which *may* be valid, or may not.
Which, frankly, is the desired behaviour.
I have to disagree.
Just throwing a warning if an implicit cast *may* happen on a
enumerator typed object is silly when the compiler can tell you that your
generic enumerator *cannot* perform the cast you want when the type is
FooBar but can't tell you that your cast on object will.

There is no reason to break existing behavior here, and a warning is
certainly not warranted. An error is when the type you request doesn't match T of any IEnumerable<T> that is available, but thats a different matter
entirely.


If I have a list<string> and I write foreach (ListViewItem in list) this
invokes a compiler error,
sure, but thats another matter as you already noticed.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
Nov 16 '05 #8
> Please reread my posting. there is an implicit cast from Foo to Foobar
with
will cause an exception.
Yah, I read that. I probably wasn't specific enough in my reply:
You have an array of IFoo that is filled with Foo objects, and you are
casting them to a FooBar.

With an array, you might be casting from Foo to FooBar because the compiler
optimizes out the enumerator. But with most collections, you are really
casting from Object to FooBar. This is because the enumerator returns type
Object, as defined in IEnumerator.Cur rent;

Now, I sort of see your point. Except from where I'm sitting, the real
issue is
semantics. Because I know that IEnumerator.Cur rent returns type Object, I
consider every foreach() statement to include an _explicit_ cast (from
object to something). Knowing about IEnumerator, that's just how I "parse"
the code in my head as I'm reading it. So when I read your initial post,
it seemed to me that every foreach would generate a compiler warning (except
for foreach(
object myObject in aCollection)

I guess if you're not coming from that point of view, it makes the foreach
look as though it might sometimes be performing an implicit cast. I haven't
looked at the IL to proof it, but I think that it's more accurate to view
every foreach as including a cast, until/unless generics are applied to
enumerators.
"cody" <pl************ *************@g mx.de> wrote in message
news:u$******** ******@tk2msftn gp13.phx.gbl...
I'm not sure that I follow your argument, but I'd like to understand it
better. The code example that you created would be invalid with or

without
generics. I only see an explicit cast in the code (technically, it's
probably from object to FooBar, because the enumerator probably returns
object)

Please reread my posting. there is an implicit cast from Foo to Foobar

with will cause an exception.

But see how dangerous foreach is: even if pointed to the problem people do
not see the invalid cast :)

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk


Nov 16 '05 #9
Cody:

A collection of object might be reaching a little, but I can definitely see
a heterogeneous collection. You might be accessing objects polymorphically .
If you want to see an example of that, you need look no further than
Winforms. System.Windows. Forms.Control.C ontrols (returns a collection of
controls that are owned by the control. They all derive from Control, but
some could be textboxes, some could be buttons, radio buttons, etc). A
generic collection of Collection<Text box> would not be sufficient.

While this is not quite the same thing as a collection of object, the
semantics are pretty close: a collection of objects that are of the same
base class, but are heterogeneous in nature. The same type of foreach error
would be possible:

// assuming that this code is in a member method of a form
foreach(Textbox in this.Controls) // oops -- blows up on the first
non-textbox in the controls collection
{}
"cody" <no************ ****@gmx.net> wrote in message
news:eN******** ******@tk2msftn gp13.phx.gbl...
foreach does implicitly cast every object in the collection to the
specified
taget type without warning.
Without generics this behaviour had the advantage of less typing for us since casting was neccessary in nearly every collection. But with generics I
consider this feature of foreach as dangerous. Casting is now almost
always
unwanted.

interface IFoo{}
class Foo:IFoo{}
class FooBar:IFoo{}

IFoo[] fooarray = {new Foo()} ;

foreach (FooBar in fooarray) // oops InvalidCastExce ption
{
}

My proposal is now that foreach should in future emit a compiler warning if
implicit cast would occur.
The problem is that, without generics, you don't have a choice. And, sorry to say it, assuming that everything will be generic is short sighted.


Tell me one reason why to use collections containing objects.
This should only be used very very rarely and with lots ofconsideration
done.
You
will have to deal with collections typed as object for a long time to

come.
foreach isn't dangerous in itself, its the developers fault if anything
fails, especially consdiering you defined the type and should be aware

that
means a cast. If you have a collection that isn't strongly typed and you

are
concerned it may hold incorrect data, you should be using for and as.


Strictly speaking, there is no such thing like "strongly typed". If a have

a conventional list, it can contain object and all of its descendants.
If I have a list<IFoo> it can contain IFoo and *all* of its implementing
classes.

Maybe we have to invent a new feature will really allows "very strongly
typed" collections, so that exactly one certain type is allowed, but this
cannot be caught by the compiler.
Having said that, the compiler should catch you if you use a type that an IEnumerable<T> cannot cast or convert to.
As I said the compiler won't complain it an implicit cast from baseclass

to descentant will take place which *may* be valid, or may not.
Which, frankly, is the desired behaviour.


I have to disagree.
Just throwing a warning if an implicit cast *may* happen on a
enumerator typed object is silly when the compiler can tell you that your generic enumerator *cannot* perform the cast you want when the type is
FooBar but can't tell you that your cast on object will.

There is no reason to break existing behavior here, and a warning is
certainly not warranted. An error is when the type you request doesn't

match
T of any IEnumerable<T> that is available, but thats a different matter
entirely.


If I have a list<string> and I write foreach (ListViewItem in list) this
invokes a compiler error,
sure, but thats another matter as you already noticed.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk

Nov 16 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
1727
by: Derek Fountain | last post by:
I was just writing a sanitisation route for a bit of user input. The data is an English text description of a product, and will go into a DB, then back out to other user's browsers. As per normal practise, I was working on the basis of leaving in all characters that I considered safe and stripping out everything else. This led me to think of what characters are actually safe, given that the user will want to be able to use at least basic...
32
4155
by: James Curran | last post by:
I'd like to make the following proposal for a new feature for the C# language. I have no connection with the C# team at Microsoft. I'm posting it here to gather input to refine it, in an "open Source" manner, and in an attempt to build a ground-swell of support to convince the folks at Microsoft to add it. Proposal: "first:" "last:" sections in a "foreach" block The problem: The foreach statement allows iterating over all the...
104
7202
by: cody | last post by:
What about an enhancement of foreach loops which allows a syntax like that: foeach(int i in 1..10) { } // forward foeach(int i in 99..2) { } // backwards foeach(char c in 'a'..'z') { } // chars foeach(Color c in Red..Blue) { } // using enums It should work with all integral datatypes. Maybe we can step a bit further: foeach(int i in 1..10, 30..100) { } // from 1 to 10 and 30 to hundred
3
3299
by: cody | last post by:
why foreach does always have to declare a new variable? I have to write foreach (int n in array){} but Iam not allowed to write: int n=0; foreach (n in array){}
1
4585
by: caldera | last post by:
Hi, I want to find the web user control in the datalist. I iterate the datalist using foreach statement in the DataListItem and in thi DataListItem I iterate all Controls objects but I can't find web user control, but I found that it is in the namedcontrols. How can I find the web user control using foreach in the datalist Thanks.
302
18618
by: Lee | last post by:
Hi Whenever I use the gets() function, the gnu c compiler gives a warning that it is dangerous to use gets(). Is this due to the possibility of array overflow? Is it correct that the program flow can be altered by giving some specific calculated inputs to gets()? How could anyone do so once the executable binary have been generated? I have heard many of the security problems and other bugs are due to array overflows.
1
6754
by: levidicom | last post by:
foreach($test as $var1){ foreach($test2 as $var2) { echo '"var1: " . $var1 . "<br>"var2: " . $var2 . "<br> \n"'; }
2
1472
by: Tamer Ibrahim | last post by:
Hi, foreach is not able to iterate through the collection because there is no public GetEnumerator method the foreach is not working in this code snippet, How can I resolve this ? bool ValidatingReservation()
233
8708
by: Julian | last post by:
'evening. I'm not new to C and have been programming in it since I was 8 but here's a strange problem I've never seen before. When I compile a program from our C course with a windows compiler there is no problem but when I try to compile it with a linux compiler it complains that a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
0
9656
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10364
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10172
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9967
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8993
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7517
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6750
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4069
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3670
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.