Re: foreach considered dangerous?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Daniel O'Connell [C# MVP] (onyxkirx_at_--NOSPAM--comcast.net)
Date: 05/06/04


Date: Thu, 6 May 2004 18:14:15 -0500


"cody" <no_spam_deutronium@gmx.net> wrote in message
news:%23eHSu63MEHA.3312@tk2msftngp13.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 InvalidCastException
> {
> }
>
> 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
>
>



Relevant Pages

  • Re: foreach considered dangerous?
    ... >> The problem is that, without generics, you don't have a choice. ... >> means a cast. ... your a fool if you do that with foreach. ... > cannot be caught by the compiler. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Whats wrong with this sentence?
    ... avoid this warning by implementing Map interface and having something ... At run time there is no generic information, so the cast is "raw" anyway. ... It's what people don't like about Java generics, and there are proposals afoot to use "reified generics", i.e., generics that work at run time. ...
    (comp.lang.java.programmer)
  • Re: A question related to type casting
    ... cast" warning for the cast to a raw List. ... compiler passes the code, ... I prefer no warnings when I compile, but they aren't a restriction on the code itself, and I'm not seeing the warning you describe anyway. ... The only reason it works now is that generics are strictly compile-time, and so there's not actually any difference between the raw List type and a parameterized reference to the generic List. ...
    (comp.lang.java.programmer)
  • generics and type checking
    ... I'm giving generics a shot, and I'm getting this warning: Type safety: ... The cast from Object to ArrayListis actually checking against ... gained by adding the 4 instances of <RequestBean> was not having to cast to ...
    (comp.lang.java.programmer)
  • Re: foreach with generics and without generics
    ... but in the foreach below I don't have to use ... If you look at the IL generated by the compiler, you'll see that the cast is implicit. ... Normally the code you write is different when you use generics compared to ... For example if you compare between implementing IComparable and ...
    (microsoft.public.dotnet.languages.csharp)