考虑到这一代码
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] strings = new string[] { "Test1", "Test2", "Test3" };
int[] ints = new int[] { 1, 2, 3, 4 };
Test(strings);
Test(ints);
}
public static void Test(params object[] objects)
{
}
}
}
而这个页面https://msdn.microsoft.com/fr-ca/library/w5zay9db.aspx
我期望(params对象[]对象)为一个元件的阵列与串[]作为第一个元素,但是当我调试,我看到(params对象[]对象)为{“测试1”,“的Test2 ”, “Test3的”}。
然而,随着一个int [],我得到一个对象[]为int []作为第一个元素。
这是不确定的行为? 这是否依赖于.NET Framework版本/单声道的版本?
Nice find!
Is this undefined behavior?
No. This is by-design behaviour. Weird design, but by design.
Does that depend on the .Net framework version / Mono version?
No. All versions of C# have this behaviour.
This is a consequence of the collision of some interesting rules of C#.
The first relevant rule is: a method with a params array may be called in either "normal" or "expanded" form. Normal form is as if there was no "params". Expanded form takes the params and bundles them up into an array that is automatically generated. If both forms are applicable then normal form wins over expanded form.
Now, that perhaps seems sensible; if you have an array of objects in hand, odds are good that you want to pass the array of objects, not an array that contains an array of objects.
The second relevant rule is that C# allows unsafe array covariance when the element type is a reference type. That is, an array of strings may be converted to an array of objects implicitly. You'll note that this has two implications. First, it means that when you have an array of objects, it might actually be an array of strings, so putting, say, a turtle into that array of objects might cause a type error. This is very surprising! You expect that every array of objects can take any object, but that is not true in C#. Some arrays of objects are lying.
The second implication is: since putting that turtle into what is really an array of strings must throw, it means that every time you put something into an array of base type, the runtime must verify that the types check. So array writes are extra expensive in C# on every write, so that the vanishingly small minority of bad writes can be caught.
This is a mess, and this is why unsafe array covariance tops my list of unfortunate C# features.
The combination of these two rules explains your observations. The array of strings is convertible to an array of objects, and therefore the method is applicable in normal form.
For the array of ints, well, covariance does not apply to value types. So the array of ints is not convertible to an array of objects, so the method is not applicable in its normal form. But an array of ints is an object, so it is applicable in expanded form.
See also:
Why does params behave like this?
Your question is arguably a duplicate of:
Is there a way to distingish myFunc(1, 2, 3) from myFunc(new int[] { 1, 2, 3 })?
我不是专家,但在params
关键字想法是使posibility做出不同的调用独立的,你有多少个元素有方法。
Test(object1)
Test(object1, object2)
Test(object1,..., objectN)
所以你看到的是正常的行为没有什么奇怪的。 在这个环节更多信息MSDN
通过使用params关键字,你可以指定采用可变数量的参数的方法参数。
您可以发送一个逗号分隔的参数声明或指定类型的参数数组指定类型的参数列表。 您还可以发送不带参数。 如果你不发送参数,PARAMS列表的长度为零。
没有额外的参数在方法声明的params关键字之后是允许的,并且仅一个params关键字在方法声明是允许的。
public static void Test(params string[] strings)
{
}
Test(string1)
Test(string1, string2)
等字符串1 ... stringN。