Basically, your method signature takes one or more objects and combines them into an array called myParam .
If several objects are transmitted individually, for example, UsingParams(1, "hello", ...) , they are automatically converted to the object[] array. This is a trick / syntax sugar compiler.
If the transferred object is not an array of object[] or a list of individual objects, it will become the first argument of your array. In other words, if you pass int[] , then your myParam will be an array whose first element is an array, which makes it a jagged array. This is because int[] is an object , and the compiler is not smart enough to understand what you are doing, and makes it the only element of the object[] array. There is no implicit cast from int[] to object[] , and therefore this does not happen.
The only time you can pass an array that will fill up as you expected is when the array type is object[] , for example new object[] { 1, "hello", ... } or the array type is covariant. In this case, the string[] array is covariant and can be implicitly transferred to object[] , but int[] cannot.
In short:
UsingParams(1, "hello") = good
UsingParams(new object[] { 1, "hello" }) = good
UsingParams(new string[] { "hi", "hello" }) = good (due to covariance of the array)
UsingParams(new int[] { 1, 2 }) = bad (no array covariance), will be a jagged array
Further reading of the rules for array covariance , which also says: โThe covariance of arrays does not specifically apply to arrays of type values. For example, there is no conversion, which allows int[] be processed as object[] .