C# 中“dynamic”和“object”关键字有什么区别? [复制]

2024-04-25

谁能简单解释一下 C# 中“dynamic”和“object”关键字之间的区别?


object :

让我们先快速浏览一下 object 关键字。我不会谈论太多,因为它从 C# 1.0 就已经存在了。该关键字只不过是 System.Object 的快捷方式,System.Object 是 C# 类层次结构中的根类型。 (但是,正如 Eric Lippert 在他的博客文章中指出的那样,C# 中并非所有内容都派生自对象。)这是一种强大的机制,因为您可以为该类型的实例分配几乎任何值。

这是一个简短的示例,演示了使用 object 关键字的一些好处和问题。

object obj = 10;
Console.WriteLine(obj.GetType());
// Prints System.Int32 because 
// this is the type of the value stored in this object.

// A compiler error, because 
// at compile time the type of obj is System.Object.
// obj = obj + 10; 

// You need to explicitly cast obj to a necessary type.
obj = (int)obj + 10;

// However, this does not mean that you are really safe. 
// You can cast to a wrong type 
// and the compiler will not detect it. 
// Here you get an exception at run time, 
// because obj is an integer, not a string.
// obj = (string)obj + 10;

// You also get a run-time exception 
// if you cast to a wrong numeric type, 
// even if there is an implicit conversion in the language.
// obj = (double)obj + 10;

正如您所看到的,虽然 obj 存储一个整数,但编译器不允许您在没有强制转换的情况下执行任何数学运算。看起来转换似乎可以帮助您确保确实拥有一个整数,但事实并非如此。您可以转换为完全不同的类型,编译器不会检测到它。结果,您会遇到运行时异常。

因此,您必须执行显式强制转换,这不能保证任何结果,因为编译器不允许您在没有强制转换的情况下运行程序。

dynamic :

这就是 C# 4.0 中新的动态关键字的用武之地。它告诉编译器不要对代码强制执行附加规则。

dynamic dyn = 10;
Console.WriteLine(dyn.GetType());
// Same as "object". 
// Prints System.Int32 because 
// this is the type of the value stored in this object.

// No compiler error, because 
// the compiler does not try to identify 
// the type of the dynamic object at compile time.
dyn = dyn + 10;

// Also, this operation will succeed for all numeric 
// or other types that support a “+” operation.
dyn = 10.0;
dyn = dyn + 10;

dyn = "10";
dyn = dyn + 10;

这是对象和动态之间的主要区别之一 - 使用动态,您可以告诉编译器对象的类型只能在运行时知道,并且编译器不会尝试干扰。因此,您可以编写更少的代码。而且我想强调的是,这并不比使用原始 object 关键字更危险。然而,它也同样危险,因此操作对象时需要使用的所有类型检查技术(例如反射)也必须用于动态对象。

经常出现的下一个问题如下:“由于动态对象可以是任何东西,并且编译器不会检查它是什么,这是否意味着您可以将动态对象传递给我毫无戒心的方法/系统并制作它崩溃了吗?”

假设我们有一个简单的方法。

public static void Print(string arg)
{
    Console.WriteLine(arg);
}
Now let’s look at how you can pass a dynamic object to it.

dynamic dyn = 10;

// You get an exception at run time here.
Print(dyn);

正如您所看到的,虽然编译器允许您将动态对象传递给您的方法,但如果该对象的类型错误,您的方法永远不会获取该对象。在实际调用方法之前抛出异常。将动态对象传递给方法的唯一方法是它是否包含必要的值(在本例中为字符串)。

dynamic dyn = "10";
Print(dyn);

同样,这与使用 object 关键字获得的行为没有太大区别。

object obj = 10;

// Doesn't compile.
//Print(obj);

// Compiles, but there is an exception at run time.
//Print((string)obj);

// This code works because obj is now a string, 
// but you still need a cast.
obj = "10";
Print((string)obj);

有人说 (int)obj 读起来不难,何必费劲去搞动态呢?嗯,在某些情况下,您必须执行如此多的强制转换操作,这使得您的代码几乎不可读。在某些情况下,简单的强制转换还不够,您必须调用反射方法,例如 InvokeMember 或 GetProperties。 COM 互操作就是一个很好的例子,这就是为什么它被修改为使用新的动态功能(有关更多信息,请查看此“操作方法”。)

此外,dynamic 关键字和动态语言运行时使许多以前不可能或难以实现的场景成为可能,包括与动态语言的互操作。我之前在本博客中强调了几个这样的场景:介绍 ExpandoObject 和使用 DynamicObject 创建包装器。

结论 :

结论是,无需担心有人可以通过使用动态功能来破坏您的代码。它并不比 object 关键字更危险(同样也同样危险)。

因此,如果您经常使用 object 关键字并且必须执行大量转换和/或使用反射来调用对象的方法和属性,那么您可能应该看看dynamic 关键字。在某些情况下,它比对象更方便,并且需要编写的代码更少。

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

C# 中“dynamic”和“object”关键字有什么区别? [复制] 的相关文章

  • 当属性名称与实体名称匹配时,实体框架将“1”附加到属性名称

    我正在使用实体框架 4 0 版使用数据库优先方法创建模型 在数据库中 有许多表包含与其父表名称相同的列 例如我们有 表 State 包含 State 和 StateName 列 表状态 包含状态和描述列 问题在于 当将这些表之一导入 EF
  • 验证使用 BER/DER 编码的 ASN.1 格式的 C# 中的 DSA 签名

    如何在 C 中验证 DSA 签名 Given 消息文本 签名摘要 通常为 ASN 1 DER 格式 公钥 采用签名的 X 509 证书 PEM 或 DER 格式 我尝试了多种方法 但都没有成功 OpenSSL NET http openss
  • 在 C# 中追加到空字符串是如何工作的?

    我很惊讶地看到一个字符串被初始化为 null 然后在生产环境中附加一些内容的示例 只是闻起来不对劲 我确信它会抛出空对象异常 但这个大大简化的示例也有效 string sample null sample test sample equal
  • Xamarin 中 QR 扫描后的处理对话框

    我在Xamarin应用程序中使用QR码扫描仪 当它扫描QR码时 它会执行一些操作 大约需要一分钟 而在执行操作时 我想在屏幕上显示一个加载对话框 但是 它没有显示在屏幕上 并且在应用程序的其他地方 它运行得很好 Code var expec
  • 如何取消 NetworkStream.ReadAsync 而不关闭流

    我正在尝试使用 NetworkStream ReadAsync 读取数据 但我找不到如何取消调用后的 ReadAsync 作为背景 NetworkStream 由连接的 BluetoothClient 对象 来自 32Feet NET 蓝牙
  • 通过网络共享的 SQL CE

    我之前见过这个问题 但找不到关于什么是可能 不可能以及什么解决方法可能可用的明确解释 我有一个现有的 C 应用程序 它使用 SQL CE 来存储本地信息 该数据库只能由单个应用程序访问 并存储在用户的 appdata 文件夹中 某些环境将
  • C#中为什么需要锁和对象?

    这是我一直不明白的事情 创建一个虚拟对象几乎看起来像是一个黑客locked 就像例子一样 class Account decimal balance private Object thisLock new Object public voi
  • 正则表达式获取“-”之前的所有字符

    如何获取字符之前的字符串 使用正则表达式 例如 我有 text 1 我想回来 text 所以我看到了实现这一目标的许多可能性 string text Foobar test 正则表达式 匹配所有内容 直到第一个 Match result R
  • 反序列化时出现 Protobuf-net memcache 提供程序 null 类型错误

    我正在使用最新的 protobuf net lib 和 protobuf net memcache 提供程序 我需要序列化自定义类型 MyClass 的列表 ProtoContract public class MyClass ProtoM
  • 强制加载 WPF 视觉对象的适当方法

    我一直在努力使用打印System Printing http msdn microsoft com en us library system printing aspx命名空间 我终于发现 在使用部分 API 时得到空白结果的原因是Visu
  • 如何在 C# 中搜索 Excel 文件

    我正在使用的代码 private void OpenExcelFile Excel Application exlApp new Microsoft Office Interop Excel Application if exlApp nu
  • 发起TCP连接关闭后如何接收数据?

    TCP 允许一侧发出 FIN 并让另一侧在结束其一侧的连接之前响应一些数据 我如何使用 NET 来实现这一点TcpClient 看来我必须使用Close发出FIN 但之后我不能再打电话Client Receive since Client被
  • 从 ALT+TAB 菜单隐藏无边框窗口

    我正在开发一个带有无边界表单的托盘应用程序 该应用程序在后台运行 如果用户想要执行不同的操作 他们可以通过右键单击托盘图标 NotifyIcon 来打开上下文菜单 所以我的要求是 1 应用程序始终以最小化模式启动 并且将显示托盘图标 2 应
  • CvMat 和 Imread 与 IpImage 和 CvLoadImage

    使用 OpenCv 2 4 我有两个选项来加载图像 1 CvMat and Imread 2 IpImage and CvLoadImage 使用哪一个更好 我尝试将两者混合并最终出现段错误 imread返回一个Mat not CvMat
  • FileStream - “不支持给定路径的格式”

    我正在尝试使用EPPlus http epplus codeplex com 在我们的 LAN 上保存电子表格 我正在使用一个FileStream对象执行此操作 但是每当我尝试实例化该对象时 我都会收到错误 The given path s
  • 从网站保存嵌入的 pdf

    我正在编写一个小型 C 应用程序来管理供应商提供的 化学品 安全数据表 目前 我手动搜索该化学品并保存 pdf 并在我的程序中添加指向 pdf 的链接 问题是我还有很多化学品需要处理 所以最好将过程自动化 例如 化学品的部件号如下 2710
  • 您在 C# 或 .NET 中见过的最奇怪的极端情况是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Microsoft 开源 .NET 后 CoreCLR 与 Mono 项目的关系

    有人可以向我解释一下 Mono 和 Microsoft 最近提供的开源 Linux 可移植 NET 堆栈 CoreCLR CoreFX Roslyn ASP NET 之间当前的关系吗 很明显这些项目是重叠的 所以我很好奇它们两个的路线图是什
  • 如何修复 Delphi Prism ASP.NET 错误:“解析器错误消息:‘Oxygene’不是受支持的语言”

    我在 Delphi Prism 中编写了一个 ASP NET Web 应用程序 不是网站 在我的开发机器上一切正常 但是当我将其安装在测试服务器上时 出现以下错误 Server Error in MyApp Application Pars
  • 如果 foreach 是一个结构数组,它会复制每个元素吗?

    我有一个结构数组 做foreach运算符在迭代数组时复制每个元素 据我所理解foreach只是底层的语法糖转换为for 所以看来答案是否定的 但我很想得到一些确认 PS 看来应该有人已经问过了 但我无法轻易找到任何东西 因此 请以提供的参考

随机推荐

  • 使用 MUI 按钮时:类型错误:无法读取未定义的属性“borderRadius”

    import React Component from react import App css import Screen from components Screen Screen import Button from componen
  • 如何在sqlite中向dateTime添加时间?

    我有一张桌子 桌子上有一个日期创建日期 像这样存储时间戳 2013 12 23 10 07 42 2013 12 23 10 14 11 实际上我正在使用 mysql2sqlite sh 脚本将数据库从 mysql 转换为 sqlite 在
  • 在 FragmentManager 上调用 popBackStack 时的 customAnimation

    在我的活动中 通过触摸按钮 我可以使用自定义动画将当前片段替换为新片段 如本例所示 Override public boolean onOptionsItemSelected MenuItem item Handle presses on
  • SATA 驱动器的硬盘 ID

    我正在为我的软件使用硬盘 ID 来检查真实用户是否正在使用该软件 对于 IDE 类型硬盘 我使用过程 GetIdeSerialNumber 获取 id 但如果是 SATA 驱动器 则 ID 为空 然后 对于 SATA 驱动器 我使用卷 ID
  • 了解荷兰国旗计划

    我正在读荷兰国旗问题 http en wikipedia org wiki Dutch national flag problem 但无法理解什么low and high参数在threeWayPartitionC 实现中的函数 如果我假设它
  • VBA Tab 键将实际的 Tab 值放入文本框中,而不是导航到下一个控件

    我有一个包含文本框的 VBA 表单 如果重要的话 在 Excel 中 有三次 我发现自己按 Tab 键导航到下一个控件 但实际的 TAB 却被放入文本框中 该形态通常会发挥应有的作用 但令我担心的是 这个小妖怪偶尔会出现 它已显示在两台不同
  • 获取 jQuery 中的“translateX”位置

    此代码设置 translateX 位置 var pos 500px slide css webkit transform translateX pos px 但是 以下代码没有获取translateX位置 var currTrans sli
  • 将 D3 svg 保存为高质量图像

    有没有办法将 D3 SVG 图像保存为高质量图像 如果是的话请解释一下 截至目前 我正在使用以下代码将 svg 保存为图像 但我得到的图像质量不高 var canvas1 document createElement canvas canv
  • 如何使用 matplotlib 绘制与比例无关的箭头

    我使用 matplotlib 在 python 中绘制了一条船的轨迹图 如下所示 现在我想添加一些箭头 例如风向 真实航向等 但是 无论绘图处于哪个缩放级别 我都希望箭头具有相同的大小 我尝试了 matplotlib pyplot arro
  • 在asp.net MVC中不使用LabelFor Helper获取DisplayName属性

    检索模型中项目的显示名称属性的最佳方法是什么 我看到很多人使用 LabelFor 助手来处理所有事情 但如果我只想列出数据 则标签不合适 如果我只想将其打印出来 比如说一个段落 是否有一种简单的方法可以获取名称属性 p p p 显然 为了避
  • 从 Xcode 分发时分析应用程序版本时出现什么错误?

    我想分发应用程序 但收到错误消息 我不知道原因 我使用 Xcode 版本 13 0 13A233 遇到错误 Error Analyzing App Version Build number request failed with error
  • 适用于 Hotmail、Gmail 和 Yahoo 的 PHP API? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 C# 中调整图像大小并保持宽高比

    我需要知道一种方法来调整图像大小以适合盒子 而不会使图像拉伸太多 该框已设置宽度和高度 我希望图像尽可能多地填充框 但保持其原始的纵横比 calculate the ratio double dbl double image Width d
  • cronjob 上的 PHP 错误,在提示时工作正常

    我正在 cronjob 上运行以下脚本 cd etc parselog php run all php gt dev null 并收到以下错误 05 May 2009 20 30 12 PHP Warning PHP Startup Una
  • 如何仅使用 CSS 制作图像轮播?

    我正在寻找制作一个图像轮播 用户可以通过单击箭头在图像之间切换 例如 但是 我只能使用 HTML 和 CSS 不能使用 JavaScript 因此也不能使用 jQuery 我只需要基本设置 平滑过渡等不是必需的 我怎样才能做到这一点 这很容
  • 无效参数:隔离消息中的非法参数:(对象是aReceivePort)

    我不确定我在这段代码中是否做错了什么 但我在生成新隔离时显然传递了 SendPort 但是当我调用时 Infrastructure instance initialize 我收到以下异常 Invalid argument s Illegal
  • int q = {1,2};特殊的初始化列表

    我遇到了下面的初始化 可以看出VS2012 显示一个错误 抱怨初始化程序太多 在海湾合作委员会看来 返回第一个元素作为值 为什么 GCC 支持这种特殊的初始化 include
  • Git 日志仅获取特定分支的提交

    我想列出仅属于特定分支的所有提交 通过以下内容 它列出了来自分支的所有提交 也列出了来自父级 主 的所有提交 git log mybranch 我发现的另一个选项是排除 master 可到达的提交并给我我想要的东西 但我想避免需要知道其他分
  • 如何交换“NSMutableDictionary”键和值?

    我有一个NSMutableDictionary我想交换值和键 即 交换值后成为键 并且其对应的键成为值 所有键和值都是唯一的 寻找就地解决方案 因为尺寸非常大 此外 键和值是NSString物体 NSMutableDictionary d
  • C# 中“dynamic”和“object”关键字有什么区别? [复制]

    这个问题在这里已经有答案了 谁能简单解释一下 C 中 dynamic 和 object 关键字之间的区别 object 让我们先快速浏览一下 object 关键字 我不会谈论太多 因为它从 C 1 0 就已经存在了 该关键字只不过是 Sys