C# params object[] 奇怪的行为

2024-02-02

考虑这段代码

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 https://msdn.microsoft.com/fr-ca/library/w5zay9db.aspx

我希望 (params object[]objects) 是一个由一个元素组成的数组,其中第一个元素是 string[],但是当我调试时,我看到 (paramsobject[]objects) 是 { "Test1", "Test2 ”,“测试3”}。

但是,使用 int[],我得到一个以 int[] 作为第一个元素的 object[]。

这是未定义的行为吗?这取决于.Net框架版本/Mono版本吗?


不错的发现!

这是未定义的行为吗?

不,这是设计使然。奇怪的设计,但却是有意为之。

这取决于.Net框架版本/Mono版本吗?

不会。所有版本的 C# 都有此行为。

这是 C# 的一些有趣规则发生冲突的结果。

第一个相关规则是:具有 params 数组的方法可以以“正常”或“扩展”形式调用。正常形式就好像没有“params”。扩展形式采用参数并将它们捆绑到自动生成的数组中。如果两种形式都适用,那么普通形式胜过扩展形式.

现在看来,这或许是明智的。如果您手头有一个对象数组,那么您很可能希望传递对象数组,而不是包含对象数组的数组。

第二条相关规则是 C# 允许当元素类型是引用类型时不安全的数组协方差。也就是说,字符串数组可以隐式转换为对象数组。您会注意到这有两个含义。首先,这意味着当你有一个对象数组时,它可能actually是一个字符串数组,因此将海龟放入该对象数组中可能会导致类型错误。这是非常令人惊讶的!您期望每个对象数组都可以接受任何对象,但在 C# 中并非如此。一些物体阵列正在撒谎。

第二个含义是:由于将海龟放入真正的字符串数组中必须抛出,这意味着每次将某些内容放入基本类型数组时,运行时必须验证类型是否检查。所以数组写入在 C# 中是非常昂贵的every写,这样极少数的坏写就可以被捕获。

这是一团糟,这就是为什么不安全的数组协方差在我的不幸的 C# 功能列表中名列前茅。

这两条规则的结合解释了你的观察结果。字符串数组可转换为对象数组,因此该方法适用于正常形式。

对于整数数组,协方差不适用于值类型。因此,整数数组不可转换为对象数组,因此该方法不适用于其正常形式。但整数数组是一个对象,因此它适用于扩展形式。

也可以看看:

为什么 params 会有这样的行为? https://stackoverflow.com/questions/2210519/why-does-params-behave-like-this/2210603#2210603

您的问题可以说是重复的:

有没有办法区分 myFunc(1, 2, 3) 和 myFunc(new int[] { 1, 2, 3 })? https://stackoverflow.com/questions/9685259/is-there-a-way-to-distingish-myfunc1-2-3-from-myfuncnew-int-1-2-3/9711427#9711427

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# params object[] 奇怪的行为 的相关文章

  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • Numpy - 根据表示一维的坐标向量的条件替换数组中的值

    我有一个data多维数组 最后一个是距离 另一方面 我有距离向量r 例如 Data np ones 20 30 100 r np linspace 10 50 100 最后 我还有一个临界距离值列表 称为r0 使得 r0 shape Dat
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • 将多维数组转换为单数组(Javascript)

    我有一个对象数组 来自 XLSX js 解析器 因此其长度和内容各不相同 表示已给予项目的资助 简化后 它看起来像这样 var grants id p 1 location loc 1 type A funds 5000 id p 2 lo
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐