473,320 Members | 2,004 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Implicit unsafe casting in foreach? What gives?

Hey Guys,

Would anyone mind explaining why a foreach will implicitly do unsafe
casts, and if there is a way to turn this off?

Here is an example:

ulong[] vals = new ulong[] { ulong.MaxValue };
foreach (uint x in vals)
Console.WriteLine(x);

Thanks,
James

May 14 '07 #1
5 2727
James,

Unfortunately, no. From the language specification:

The type of the expression of a foreach statement must be a collection type
(as defined below), and an explicit conversion (§?6.2) must exist from the
element type of the collection to the type of the iteration variable. If
expression has the value null, a System.NullReferenceException is thrown.

Since an explicit conversion exists between ulong and uint, the compiler
is right in this case.

You can get around it yourself, though, by iterating through the
elements manually, and then performing the check of the returned type vs the
type you wish to use.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"james" <ja********@gmail.comwrote in message
news:11**********************@h2g2000hsg.googlegro ups.com...
Hey Guys,

Would anyone mind explaining why a foreach will implicitly do unsafe
casts, and if there is a way to turn this off?

Here is an example:

ulong[] vals = new ulong[] { ulong.MaxValue };
foreach (uint x in vals)
Console.WriteLine(x);

Thanks,
James

May 14 '07 #2
"james" <ja********@gmail.comwrote in message
news:11**********************@h2g2000hsg.googlegro ups.com...
Would anyone mind explaining why a foreach will implicitly do unsafe
casts, and if there is a way to turn this off?

Here is an example:

ulong[] vals = new ulong[] { ulong.MaxValue };
foreach (uint x in vals)
Console.WriteLine(x);
The reason why the foreach does an unsafe cast, is because it doesn't
know otherwise. A foreach can be done on any object that implements
IEnumerable, and IEnumerable returns a GetEnumerator which provides an
IEnumerator which has a method "Current" that returns Object. Therefore,
foreach always thinks that it is dealing with Object, so it always has to do
an unsafe cast regardless of the type of variable that you use to control
the loop. That is, the compiler translates the previous foreach to something
similar to the following:

IEnumerator e = vals.GetEnumerator();
while (e.MoveNext())
{
object obj = e.Current();
uint x= (uint) obj;
Console.WriteLine(x);
}

There is an IEnumerable<Tthat solves the preceding problem. However,
the documentation of System.Array only shows arrays to implement
IEnumerable, and not IEnumerable<typeoftheelements>.


May 14 '07 #3


Tyepd arrays do actually implement IEnumerable<T>. I'm not sure how
to prove this with the documentation, object browser, or Reflector,
but the following code demonstrates it:

private static void Test<T>(IEnumerable<TthingToEnumerate)
{
int[] ints = null;
Test(ints); // works

Array array = null;
Test(array); // doesn't work
}

Also technically a collection does not need to implement IEnumerable
to work with foreach--it only needs a GetEnumerator() method. It's
technically possible to write a class that has GetEnumerator() and
doesn't implement IEnumerable and it will still work with
foreach--although you never want to, just a silly little technicality.

Sam

------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.

On Mon, 14 May 2007 18:50:42 +0200, "Alberto Poblacion"
<ea******************************@poblacion.orgwro te:
>
The reason why the foreach does an unsafe cast, is because it doesn't
know otherwise. A foreach can be done on any object that implements
IEnumerable, and IEnumerable returns a GetEnumerator which provides an
IEnumerator which has a method "Current" that returns Object. Therefore,
foreach always thinks that it is dealing with Object, so it always has to do
an unsafe cast regardless of the type of variable that you use to control
the loop. That is, the compiler translates the previous foreach to something
similar to the following:

IEnumerator e = vals.GetEnumerator();
while (e.MoveNext())
{
object obj = e.Current();
uint x= (uint) obj;
Console.WriteLine(x);
}

There is an IEnumerable<Tthat solves the preceding problem. However,
the documentation of System.Array only shows arrays to implement
IEnumerable, and not IEnumerable<typeoftheelements>.
May 14 '07 #4
Alberto Poblacion <ea******************************@poblacion.org>
wrote:

<snip>
The reason why the foreach does an unsafe cast, is because it doesn't
know otherwise. A foreach can be done on any object that implements
IEnumerable, and IEnumerable returns a GetEnumerator which provides an
IEnumerator which has a method "Current" that returns Object. Therefore,
foreach always thinks that it is dealing with Object, so it always has to do
an unsafe cast regardless of the type of variable that you use to control
the loop.
That's not quite true. This doesn't compile, for instance:

using System;

class Test
{
static void Main()
{
int[] array = new int[10];
foreach (string x in array)
{
Console.WriteLine (x);
}
}
}

and using generics, things get better even for collections:

using System;
using System.Collections.Generic;
using System.IO;

class Test
{
static void Main()
{
List<Streamlist = new List<Stream>();
foreach (string x in list)
{
Console.WriteLine (x);
}
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 14 '07 #5
"Samuel R. Neff" <sa********@nomail.comschrieb im Newsbeitrag
news:fe********************************@4ax.com...
>

Tyepd arrays do actually implement IEnumerable<T>. I'm not sure how
to prove this with the documentation,
citation from the specs (C#2.0 ECMA):
A one-dimensional array S[] implements the interface
System.Collections.Generic.IList<S>
(IList<Sfor short) and its base interfaces.

The spec of C#1.0 shall have an analog sentence without generics.

Christof
May 15 '07 #6

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

Similar topics

4
by: Simon Ford | last post by:
Hi All, I'm having trouble understanding exactly how I can do some specific implicit casting. There are two problems here; does anyone know what I should be doing? //---------- // (1)...
9
by: Simon | last post by:
Hi All, Is it possible to disallow implicit casting for an operand of a function written in C? i.e. void foo(int a) {..} short b; foo(b) // error without explicit cast
8
by: Roger Leigh | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 A lot of functions use const pointer arguments. If I have a non-const pointer, it is transparently made const when I pass it to the function, e.g....
11
by: Steve Gough | last post by:
Could anyone please help me to understand what is happening here? The commented line produces an error, which is what I expected given that there is no conversion defined from type double to type...
9
by: Kurt | last post by:
Hi I was trying to get this VB type code to work in C Sub SetColumns_Example( Dim ol As Outlook.Applicatio Dim MyFolder As MAPIFolde Dim itms As Item Dim itm As Objec Dim dtmStart As Date,...
6
by: Gecko | last post by:
I would like to know if there is a way to stop the runtime from implicitly casting values. For exampel, I would like the following code to crash: byte someByte = 5; int someInt = someByte; I...
36
by: Chad Z. Hower aka Kudzu | last post by:
I have an implicit conversion set up in an assembly from a Stream to something else. In C#, it works. In VB it does not. Does VB support implicit conversions? And if so any idea why it would work...
10
by: Pieter Breed | last post by:
Hi All, Please excuse me, but the bulk of my post will be a code post. It describes some weirdness with regards to the implicit casting operator. The crux of the problem is this: I want to...
5
by: johanatan | last post by:
Does anyone know the reasons for the lack of an implicit casting operator in any greater depth than: A. Automatic conversion is believed to be too error prone. (from the FAQ at the bottom of:...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.