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

R

Richard Everett

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?
 
P

Pavel Minaev

Richard said:
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/arc...s-using-explicitly-typed-range-variables.aspx

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())
 
J

Jon Skeet [C# MVP]

Richard Everett said:
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.
 
T

Techno_Dex

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)); });
 
J

Jon Skeet [C# MVP]

Techno_Dex said:
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 :)
 
P

Pavel Minaev

Richard Everett said:
            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.
 
J

Jon Skeet [C# MVP]

Richard Everett said:
            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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top