evg*_*sa3 19 c# arrays casting params
考虑这个代码
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)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个页面https://msdn.microsoft.com/fr-ca/library/w5zay9db.aspx
我希望(params object []对象)是一个元素的数组,以字符串[]作为第一个元素,但是当我调试时,我看到(params object []对象)是{"Test1","Test2" ","Test3"}.
但是,使用int [],我得到一个object [],其中int []作为第一个元素.
这是未定义的行为吗?这取决于.Net框架版本/ Mono版本吗?
Eri*_*ert 27
很好找!
这是未定义的行为吗?
不.这是设计行为.奇怪的设计,但设计.
这取决于.Net框架版本/ Mono版本吗?
不会.所有版本的C#都有此行为.
这是一些有趣的C#规则碰撞的结果.
第一个相关规则是:具有params数组的方法可以以"正常"或"扩展"形式调用.正常形式就好像没有"参数".扩展形式使用参数并将它们捆绑成一个自动生成的数组. 如果两种形式都适用,则普通形式胜过扩展形式.
现在,这似乎是明智的; 如果您手头有一个对象数组,那么您希望传递对象数组,而不是包含对象数组的数组的几率很高.
第二个相关规则是当元素类型是引用类型时,C#允许不安全的数组协方差.也就是说,字符串数组可以隐式地转换为对象数组.你会注意到这有两个含义.首先,这意味着当你有一个对象数组时,它实际上可能是一个字符串数组,所以将乌龟放入该对象数组可能会导致类型错误.这非常令人惊讶!您希望每个对象数组都可以接受任何对象,但在C#中则不然.一些物体阵列正在撒谎.
第二个含义是:由于将该乌龟放入真正的字符串数组必须抛出,这意味着每次将某些东西放入基类型数组中时,运行时必须验证类型是否检查.因此,在每次写入时,C#中的数组写入都非常昂贵,因此可以捕获极少数不良写入.
这是一个烂摊子,这就是为什么不安全的数组协方差排在我不幸的C#特性列表之上.
这两个规则的组合解释了您的观察结果.字符串数组可以转换为对象数组,因此该方法适用于普通形式.
对于整数数组,协方差不适用于值类型.因此,int数组不能转换为对象数组,因此该方法不适用于其正常形式.但是一组int是一个对象,因此它适用于扩展形式.
也可以看看:
您的问题可以说是重复的:
有没有办法从myFunc(new int [] {1,2,3}}中删除myFunc(1,2,3)?
我不是专家,但params关键字的想法是使能够对方法进行不同的调用,而不管你有多少元素.
Test(object1)
Test(object1, object2)
Test(object1,..., objectN)
Run Code Online (Sandbox Code Playgroud)
所以你所看到的是正常行为并不奇怪.在这个环节更多信息MSDN
通过使用params关键字,您可以指定采用可变数量参数的方法参数.
您可以发送以逗号分隔的参数列表,这些参数包含在参数声明中指定的类型或指定类型的参数数组中.你也可以不发送任何参数.如果不发送参数,则params列表的长度为零.
在方法声明中的params关键字之后不允许使用其他参数,并且在方法声明中只允许使用一个params关键字.
| 归档时间: |
|
| 查看次数: |
2266 次 |
| 最近记录: |