Connecting Tech Pros Worldwide Forums | Help | Site Map

Casting arrays fails at runtime

eric.dennison@gmail.com
Guest
 
Posts: n/a
#1: Jun 8 '06
In the sample below:

testClass is derived from object.

We can cast object to testClass, no problem
We can cast testClass[] to object[] no problem
Compiler is ok with cast object[] to testClass[] but fails at runtime.

Why?

I understand this can be worked around using Array.Copy, but I actually
am trying to do the cast from object[] to testClass[] within
Type.InvokeMember and so can't get my hands on the destination
testClass[] member at compile time. Enough to make me head spin.

Heck, I don't even know how to do the cast within InvokeMember, so I'm
two levels away from a solution. Any ideas out there??

-Eric

Sample code:

public class testClass : object
{
public int testMember;
}

// this works great
public void testMethod1()
{
object[] objArray;
testClass[] testArray = new testClass[1];
objArray = testArray;
}

// this fails on the last line
public void testMethod2()
{
// first, we can cast happily from object to testClass
object objSingle = new object();
testClass testSingle;
testClass testTemp = new testClass();
testTemp.testMember = 55;
objSingle = testTemp;
testSingle = (testClass)objSingle;
// testSingle.testMember does indeed == 55

// on the other hand, if we're dealing in arrays...
object[] objArray = new object[1];
testClass[] testArray;
objArray[0] = new testClass();

// **** compiler is ok with this, but fails at runtime
****
testArray = (testClass[])objArray;
}


Barry Kelly
Guest
 
Posts: n/a
#2: Jun 8 '06

re: Casting arrays fails at runtime


eric.dennison@gmail.com wrote:
[color=blue]
> In the sample below:
>
> testClass is derived from object.
>
> We can cast object to testClass, no problem
> We can cast testClass[] to object[] no problem
> Compiler is ok with cast object[] to testClass[] but fails at runtime.[/color]

This behaviour of the .NET runtime, where T and S are types and S is a
subtype of T, where S[] can be cast to T[], seems to have been
introduced solely for compatibility with the Java language. It's
important to point out that it involves polymorphism. That is, S[]
stored in a variable of type T[] is *still*, at runtime, of type S[].

This becomes apparent when a third type, U, also derived from T, is
stored at runtime into an S[] which is being referred, polymorphically,
through a value of type T[]. (It causes a runtime exception.)

Basically, every store and load to and from an array of a reference type
is actually a virtual method call which uses dynamic dispatch based on
the runtime type of the array value.

For example:

---8<---
class App
{
static void Main()
{
string[] foo = { "a", "b" };
object[] bar = foo;
bar[0] = new App(); // Throws exception at runtime,
// because the object referred to by bar is not an object[]
// but is in fact a string[], which can't store App instances.

// That's why you can't cast an object[] value to string[],
// even if it only contains strings. It has to be a string[]
// value to begin with, when it was constructed.
}
}
--->8---
[color=blue]
> Why?[/color]

Your code tries to cast an object[] to a testClass[], but an object[] is
*not* a testClass[], even if all it contains is values
assignment-compatible with variables of type testClass[].

-- Barry

--
http://barrkel.blogspot.com/
eric.dennison@gmail.com
Guest
 
Posts: n/a
#3: Jun 8 '06

re: Casting arrays fails at runtime


> Your code tries to cast an object[] to a testClass[], but an object[] is[color=blue]
> *not* a testClass[], even if all it contains is values
> assignment-compatible with variables of type testClass[].
>[/color]

Thanks for the insight, Barry.

Looks to me like the way out is through Array.CreateInstance, where I
can generate the correct type of array at runtime (which is
fundamentally what I need to do), then drag the whole thing around as
an object reference. Had to read your answer through several times
before I shifted my thinking in the right direction.

-Eric

Closed Thread


Similar C# / C Sharp bytes