Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I convert an object (which is really object[]) to string[]?

I have a field that is of type 'object'. When I inspect it within the Watch window of visual studio I see its Object[] and when I drill into the elements I see each element is a string.

But when I try to cast this to a String[] I get this error:

Cannot cast 'MyObject' (which has an actual type of 'object[]') to 'string[]' string[]

Any reason why I can't do this cast? What is the best way to convert this object to a string array?

like image 228
leora Avatar asked Apr 13 '12 14:04

leora


1 Answers

This is a particularly confusing feature of C#. Here's the deal.

Throughout this discussion we assume that the element type of an array is a reference type, not a value type.

C# supports unsafe array covariance. That means that if you have an array of string, you can convert it to an array of object, because a string can be converted to an object:

string[] a1 = { "hello", "goodbye" };
object[] a2 = a1; // Legal

If you then try to get an element out of a2, it works:

object o3 = a2[0]; 

That's legal because a2[0] is really a1[0], which is a string, which is convertible to object.

However, if you attempt to write to the array then you'll get an error at runtime:

a2[0] = new object();

This fails at runtime because a2 is really an array of strings, and you can't put a non-string into an array of strings.

So C# is already horribly broken; it is possible to write a program that compiles and looks normal but suddenly crashes with a type exception at runtime because you tried to put an object into an array of objects that is not actually an array of objects.

The feature you want is even more broken than that, and thank goodness C# does not support it. The feature you want is:

object[] a4 = { "Hello" };
string[] a5 = a4; 

That would be unsafe array contravariance. It breaks horribly like this:

a4[0] = new Customer(); // Perfectly legal 
string s6 = a5[0]; 

And now we just copied a Customer into a variable of type string.

You should avoid any kind of array covariance or contravariance; array contravariance is, as you've discovered, not legal, and array covariance is making little time bombs in your program that go off unexpectedly. Make your arrays of the right type to begin with.

like image 93
Eric Lippert Avatar answered Sep 19 '22 02:09

Eric Lippert