Misters
Misters

Reputation: 1347

Array object[] in covariance behavior

I had a compile error while assinging int[] to object[] (the question is not mine).

The accepted answer states that that's because the array covariance (please read the question and the answer for the sake of better understanding).

Now my situation is that while I cannot assign int[] to object[] because int is value type (struct) I wonder why I can do this now:

var arrayOfObjects = new object[] { 58, 58, 78 };// it accepts values types as initializers!

Why does this work if I am initializing value types to the array object? Should not be reciprocal not accepting values types neither?

Upvotes: 3

Views: 76

Answers (3)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149558

To complete the point of view from the compilers perspective, given the following statement:

void Main()
{
    object[] or = new object[] { 1, 2 };
}

This is the IL emitted by the compiler:

IL_0001:  ldc.i4.2    
IL_0002:  newarr      System.Object
IL_0007:  stloc.1     // System.Object[]
IL_0008:  ldloc.1     // System.Object[]
IL_0009:  ldc.i4.0    
IL_000A:  ldc.i4.1    
IL_000B:  box         System.Int32
IL_0010:  stelem.ref  
IL_0011:  ldloc.1     // System.Object[]
IL_0012:  ldc.i4.1    
IL_0013:  ldc.i4.2    
IL_0014:  box         System.Int32
IL_0019:  stelem.ref  
IL_001A:  ldloc.1     // System.Object[]
IL_001B:  stloc.0     // or
IL_001C:  ret      

The compiler takes the values, does a box operation of the value type (int) and then calls stelem.ref, which replaces the value of the element at the supplied index in the one-dimensional array with the ref (type O) value pushed onto the stack.

Upvotes: 1

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

Here you are not building an int[], the integers are being boxed into objects and you're building an object[] instead. You could box other things too:

var arrayOfObjects = new object[] { true, "false", 1, 10, new StringBuilder() }

Upvotes: 2

Luaan
Luaan

Reputation: 63772

Because you're (implicitly) casting one item after another into object. You're not assigning a int[] array to a object[] variable - you're creating an object[] variable from individual int values (which get implicitly cast and boxed).

To show this without the array initializer:

object[] objarr = new object[1];
objarr[0] = 42; // Fine, translates basically into objarr[0] = (object)42;

int[] intarr = new int[1];
intarr[0] = 42; // Also fine

objarr = intarr; // No can do!

Upvotes: 7

Related Questions