Why are we getting ArrayTypeMismatch with ref parameters?

Given scenerio:

public class Program
{
    static void Main()
    {
        object[] covarientArray= new A[] { new A() };
        object polymorphism = new A();
        object test = covarientArray[0];
        M(ref polymorphism);//fine up to here

        M(ref covarientArray[0]);//ArrayTypeMismatchException
    }

    static void M(ref object o) { Console.WriteLine(o); }
}
class A {}

      

And the definition of ArrayTypeMisMatch:

The exception that is thrown when trying to store an element of the wrong type inside an array.

This exception is thrown when an attemp is created to store an element of the wrong type in an array. For example:.

A[] invalid = new A[1];
invalid[0] = "";//I can't store a type of string within an array of type of A

      

How does this exception happen? Why are we doing a store operation when calling a method with a parameter ref

?

+3


source to share


2 answers


Why are we doing a store operation when calling a method? with a ref parameter?

Providing an array element as a parameter argument is ref

actually a store operation, at least potentially. (Yes, you can't reassign it, but the compiler / runtime doesn't necessarily know this)

Imagine the implementation of the method M

is as follows:

static void M(ref object o) 
{ 
    o = new B();
}

      

If we type your covariant array like object[]

this so that it compiles and works:

object[] covariantArray= new object[] { new A() };
M(ref covariantArray[0]);
Console.WriteLine(covariantArray[0].GetType().Name); //B

      



It starts and replaces the first element with a new instance of B. Of course this works great for an array object[]

. So now if we just change it to A[]

:

object[] covariantArray= new A[] { new A() };
M(ref covariantArray[0]); //ArrayTypeMismatchException
Console.WriteLine(covariantArray[0].GetType().Name);

      

It will throw an exception before a potentially dangerous / catastrophic / dog-cat / up-down call is processed M

.

Of course, remove the calls to ref

or ref

for the local variable instead of the array element and it works great since you don't mess with the contents of the array.

@hvd's answer is probably more correct as it explains the basic execution mechanism for throwing, but at least here's a practical demonstration of why that is.

+1


source


An exception is also thrown when ref

the wrong array type is created for an element. This is admittedly unclear just by reading the text of the exception, but it is mentioned very briefly on the page you linked to:

The following Microsoft Intermediate Language (MSIL) statements throw an ArrayTypeMismatchException:

ldelema



ldelema

(load item address) is an instruction used to create a reference to an array item.

How and why, it prevents every assignment to every argument ref

from having to do a runtime check.

+3


source







All Articles