[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework

.NET 3.5 SP1 causes exception when casting arrays (using .Cast<>

Richard Everett

8/14/2008 4:05:00 PM

I just installed Service Pack 1 for the .NET Framework 3.5. The
following (greatly simplified) code now throws an exception on the
Cast<> line:

class Program
{
static void Main(string[] args)
{
int[] ints = { 1, 2, 3, 4 };

string[] strings = ints.Cast<string>().ToArray(); //
InvalidCastException
// (Unable to cast object
of type 'System.Int32' to type 'System.String'.)
}
}


Has anyone else seen this; is this a bug in SP1?
7 Answers

Pavel Minaev

8/14/2008 4:52:00 PM

0



Richard Everett wrote:
> I just installed Service Pack 1 for the .NET Framework 3.5. The
> following (greatly simplified) code now throws an exception on the
> Cast<> line:
>
> class Program
> {
> static void Main(string[] args)
> {
> int[] ints = { 1, 2, 3, 4 };
>
> string[] strings = ints.Cast<string>().ToArray(); //
> InvalidCastException
> // (Unable to cast object
> of type 'System.Int32' to type 'System.String'.)
> }
> }
>
>
> Has anyone else seen this; is this a bug in SP1?

Yes, and this is by design. Here is the explanation:

http://blogs.msdn.com/ed_maurer/archive/2008/02/16/breaking-change-in-linq-queries-using-explicitly-typed-range-vari...

Long story short, you were never supposed to do anything but object
upcasts and downcasts using Cast(). When you need to actually convert
values from one type to another, you should use Select(), and spell
out the conversion explicitly; e.g.:

ints.Select(x => x.ToString())

Jon Skeet

8/14/2008 7:08:00 PM

0

Richard Everett <richardneverett@gmail.com> wrote:
> I just installed Service Pack 1 for the .NET Framework 3.5. The
> following (greatly simplified) code now throws an exception on the
> Cast<> line:
>
> class Program
> {
> static void Main(string[] args)
> {
> int[] ints = { 1, 2, 3, 4 };
>
> string[] strings = ints.Cast<string>().ToArray(); //
> InvalidCastException
> // (Unable to cast object
> of type 'System.Int32' to type 'System.String'.)
> }
> }
>
>
> Has anyone else seen this; is this a bug in SP1?

Did the above really work before SP1? That would surprise me greatly.
What *did* work, but now doesn't, is something like:

new int[]{1, 2, 3}.Cast<double>().ToArray()

In other words where there *is* an available conversion (int to double
in this case). Pavel has given a link to an explanation.

But as there's no direct conversion available between ints and strings,
I'd be very surprised to see the above work pre-SP1.

--
Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox....
Blog: http://www.msmvps.com...
C# in Depth: http://csharpi...

Techno_Dex

8/14/2008 8:26:00 PM

0

Use anonymous delgates

List<int> liInts;
List<string> lsStrings;

liInts = new List<int>(ints);

lsStrings = liInts.ConvertAll<string>(delegate(int aiValue)
{
return
Convert.ToString(aiValue);
});



liContractItemKeys = lsContractItemKeys.ConvertAll<int>(delegate(string
asValue) { return (Convert.ToInt32(asValue)); });


"Richard Everett" <richardneverett@gmail.com> wrote in message
news:206a22ac-3d95-4781-b3e7-7b12c34d5074@r66g2000hsg.googlegroups.com...
>I just installed Service Pack 1 for the .NET Framework 3.5. The
> following (greatly simplified) code now throws an exception on the
> Cast<> line:
>
> class Program
> {
> static void Main(string[] args)
> {
> int[] ints = { 1, 2, 3, 4 };
>
> string[] strings = ints.Cast<string>().ToArray(); //
> InvalidCastException
> // (Unable to cast object
> of type 'System.Int32' to type 'System.String'.)
> }
> }
>
>
> Has anyone else seen this; is this a bug in SP1?


Jon Skeet

8/14/2008 9:58:00 PM

0

Techno_Dex <nospamchurst@osi-corp.com> wrote:
> Use anonymous delgates
>
> List<int> liInts;
> List<string> lsStrings;
>
> liInts = new List<int>(ints);
>
> lsStrings = liInts.ConvertAll<string>(delegate(int aiValue)
> {
> return
> Convert.ToString(aiValue);
> });
>
> liContractItemKeys = lsContractItemKeys.ConvertAll<int>(delegate(string
> asValue) { return (Convert.ToInt32(asValue)); });

If you're using .NET 3.5 to start with, you've got C# 3 available, so
there's a much nicer way open:

ints.Select(i => i.ToString())

That way it's still lazy too :)

--
Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox....
Blog: http://www.msmvps.com...
C# in Depth: http://csharpi...

Pavel Minaev

8/15/2008 5:54:00 AM

0

On Aug 14, 11:08 pm, Jon Skeet [C# MVP] <sk...@pobox.com> wrote:
> Richard Everett <richardnever...@gmail.com> wrote:
> >             int[] ints = { 1, 2, 3, 4 };
>
> >             string[] strings = ints.Cast<string>().ToArray(); //
>
> Did the above really work before SP1? That would surprise me greatly.

Actually, yes, it did work - it was a consequence of them using
Convert.ChangeType() (and thus IConvertible). As I understand,
previously, Cast() first tried a straightforward cast (via as), and
falled back to Convert if that failed.

Jon Skeet

8/15/2008 7:50:00 AM

0

On Aug 15, 6:54 am, Pavel Minaev <int...@gmail.com> wrote:
> > Richard Everett <richardnever...@gmail.com> wrote:
> > >             int[] ints = { 1, 2, 3, 4 };
>
> > >             string[] strings = ints.Cast<string>().ToArray(); //
>
> > Did the above really work before SP1? That would surprise me greatly.
>
> Actually, yes, it did work - it was a consequence of them using
> Convert.ChangeType() (and thus IConvertible). As I understand,
> previously, Cast() first tried a straightforward cast (via as), and
> falled back to Convert if that failed.

Yes, I've just tried it on a pre-SP1 machine - apologies for adding to
the confusion :(

Jon

Richard Everett

8/20/2008 10:28:00 AM

0

Thanks to all for the comprehensive responses!