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

  • Thread starter Thread starter Richard Everett
  • Start date Start date
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?
 
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())
 
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.
 
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)); });
 
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 :)
 
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.
 
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
 
Back
Top