3

I currently am learning about Reflection late binding from this video.

And as I replicate the code in the video, there was one part which puzzles me. It is when Invoke method is used:

MethodInfo getFullNameMethod = customerType.GetMethod("GetFullName");
string[] parameters = new string[2];
parameters[0] = "First";
parameters[1] = "Last";

//here is where I got confused...
string fullName = (string)getFullNameMethod.Invoke(customerInstance, parameters);

As far as I can see (also shown in the video) Invoke has input parameters of (object, object[]) and has no overloaded method with input parameters (object, object).

What being passed here are (object, string[]). And so, at first I expected that there would be compilation error as I thought string[] is an object rather than object[]. But.... there is no compilation error.

That puzzles me: why string[] is an object[] rather than object (every Type is C# is derived from object after all)? Can we not assign string[] as an object like this?

object obj = new string[3]; //this is OK

How can a string[] is both object and object[]? Using other data type, say int, as an analogy, I will never expect a variable as int and int[] at the same time.

Can somebody enlighten me?


Here is my full code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace ConsoleApplication2 {
    class Program {
        static void Main(string[] args) {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            Type customerType = executingAssembly.GetType("ConsoleApplication2.Customer");
            object customerInstance = Activator.CreateInstance(customerType);
            MethodInfo getFullNameMethod = customerType.GetMethod("GetFullName");
            string[] parameters = new string[2];
            parameters[0] = "First";
            parameters[1] = "Last";
            string fullName = (string)getFullNameMethod.Invoke(customerInstance, parameters);
            Console.WriteLine(fullName);
            Console.ReadKey();
        }
    }

    class Customer {
        public string GetFullName(string FirstName, string LastName) {
            return FirstName + " " + LastName;
        }
    }
}
Ian
  • 30,182
  • 19
  • 69
  • 107
  • 3
    First, every `class` and `struct` in .NET (including every array) ultimately derives from `object`, so `string[]` can be converted to `object`. Second, for compatibility with Java, arrays in .NET are "covariant", meaning that an array of type X can be converted to an array of type Y if X has a reference conversion to Y. Because `string` derives from `object`, `string[]` can be converted to `object[]`. – Michael Liu Mar 13 '16 at 03:50
  • @MichaelLiu that should be the answer! :) could you just explain a little bit more about "for compatibility with Java, arrays in .NET are covariant"? Because I am not too familiar with Java.. – Ian Mar 13 '16 at 03:59
  • 1
    Eric Lippert has a brief blog post that talks about it: https://blogs.msdn.microsoft.com/ericlippert/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance/ – Michael Liu Mar 13 '16 at 04:05
  • @MichaelLiu OK, will look at that. Thanks again. – Ian Mar 13 '16 at 04:05
  • Duplicate of http://stackoverflow.com/questions/35876463/c-sharp-params-object-strange-behavior/35876845#35876845 from yesterday, and numerous questions before that. – Eric Lippert Mar 13 '16 at 04:24

1 Answers1

2

According to section 12.5 in MSDN

For any two reference-types A and B, if an implicit reference conversion (Section 6.1.4) or explicit reference conversion (Section 6.2.3) exists from A to B, then the same reference conversion also exists from the array type A[R] to the array type B[R], where R is any given rank-specifier (but the same for both array types). This relationship is known as array covariance.

Below code is perfectly valid.

string[] items = new string[] {"A", "B", "C"};      
object[] objItems = items; 

That's why in your case, passing string[] is valid and will be converted to object[]

Hari Prasad
  • 16,716
  • 4
  • 21
  • 35