Why do params behave differently for an array of strings and an array of integers?

While writing unit tests, I came across a problem: NUnit [TestCaseAttribute]with the following constructor overloads:

public TestCaseAttribute(params object arg)
public TestCaseAttribute(params object args[])

accepts an array of integers and a list of arguments, including an array of strings, but does not accept an array of strings:

[TestCaseAttribute(new[] { 1, 2, 3 })] //works
[TestCaseAttribute("Other string", new[] { "1", "2", "3" })] //works
[TestCaseAttribute(new[] { "1", "2", "3" })] //compilation error?

This surprised me, so I checked the behavior:

private static void PrintTypes(params object[] objects)
{
    Console.WriteLine("Array type is " + objects.GetType());
    Console.WriteLine("Object count is " + objects.Length);
    Console.WriteLine("Object type is " + objects[0].GetType());
}

public static void Main()
{
    Console.WriteLine("Array of ints: ");
    PrintTypes(new[] { 1, 2, 3 });
    Console.WriteLine();
    Console.WriteLine("Array of strings: ");
    PrintTypes(new[] { "1", "2", "3" });
}

The result is somewhat confusing to me - it seems that the integer array is considered as one object, but the array of strings is expanded:

Array of ints:
Array type is System.Object[]
Object count is 1
Object type is System.Int32[]

Array of strings:
Array type is System.String[]
Object count is 3
Object type is System.String

And if we add the following method:

private static void PrintTypes(object obj)
{
    Console.WriteLine("In object method");
    Console.WriteLine("Object type is " + obj.GetType());
}

the compiler prefers it for an int array, but not for an array of strings:

Array of ints: 
In object method
Object type is System.Int32[]

Array of strings: 
In array method
Array type is System.String[]
Object count is 3
Object type is System.String

? , - , , , , , .

+4
1

int, , PrintTypes.

# (), 15.6.2.5 :

:

β€’ , , , (Β§11.2) . , .

11.2 ( ) , " " :

:

[...]

β€’ S SE T TE, :

  - S T . , S T .

  - SE TE

, . () (. 11.2 ). int [] , PrintTypes .

,

[TestCaseAttribute(new[] { 1, 2, 3 })] //works

,

[TestCaseAttribute(new[] { "1", "2", "3" })] //compilation error?

? , ?

TestCaseAttribute:

public TestCaseAttribute(params object[] arguments);
public TestCaseAttribute(object arg);
public TestCaseAttribute(object arg1, object arg2);
public TestCaseAttribute(object arg1, object arg2, object arg3);

, [TestCaseAttribute(new[] { 1, 2, 3 })] , TestCaseAttribute(object arg).

new[] { "1", "2", "3" } - , TestCaseAttribute(params object args[]) ( , 12.6.4 " " ). , , . ( 12.20 ):

. , , .

( )

. , , , string[]. , , . , , .

+3

Source: https://habr.com/ru/post/1695221/


All Articles