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”关键字有什么区别? [复制] 的相关文章

  • EasyNetQ 模型关闭

    我使用 EasyNetQ 实现了一个简单的 RabbitMQ 客户端 连接后 我收到一条通知 队列模型关闭 这是我的代码 var bus RabbitHutch CreateBus String Format host 0 hostName
  • 在 .Net 托管的 IronPython 脚本中设置和获取变量

    我正在尝试使用 Net 控制台应用程序中托管的 IronPython 来构建验证规则引擎的原型 我已经将脚本精简到我认为的基础内容 var engine Python CreateEngine engine Execute from Sys
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • 使用实体框架重叠约会

    我将 asp net mvc 与实体框架一起使用 我有一个包含 startat 字段 endat 字段和 roomid 字段 称为 SpaceConfigurationId 的约会列表 并且希望查找给定房间已重复预订的约会列表 可以假设 e
  • “你好世界!!”在 .NET 4 中生成 3500 个页面错误

    我正在运行 Windows Vista 和 Visual Studio 2010 使用 NET 4 2 GB RAM 和大约 800 MB 可用空间 我创建了一个 Windows 窗体应用程序 但没有向其中添加任何代码 只需在发布模式下编译
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 如何在完成之前从 ReplaySubject 获取最新值

    我需要一种方法来获取添加到 ReplaySubject 中符合特定条件的最新项目 下面的示例代码完成了我需要它做的事情 但感觉不是正确的方法 static void Main string args var o new ReplaySubj
  • 时间跨度格式[重复]

    这个问题在这里已经有答案了 当您将时间跨度声明为以下形式时 如何优雅地格式化时间跨度以表示 1 小时 10 分钟 TimeSpan t new TimeSpan 0 70 0 我当然知道你可以为此做一些简单的数学计算 但我有点希望 NET
  • NuGet:包含 .pdb 文件并排除“Content”文件夹

    我已将以下行合并到 CI 构建中在每个构建上创建一个私有 NuGet 包 nuget pack C Projects Test Test vbproj OutputDirectory nas1 NuGet The 读取AssemblyInf
  • 如何消除字符串中的所有换行符?

    我需要删除字符串中出现的所有换行符 来自数据库 我使用下面的代码来做到这一点 value Replace r n Replace n Replace r 我可以看到至少有一个角色的行为就像行尾一样幸存了下来 字符代码是8232 http w
  • 使一个对象只能被同一程序集中的另一个对象访问?

    每个业务对象都有一个包含 sql 调用的匹配对象 我想限制这些 sql 对象 使其只能由匹配的业务对象使用 如何才能实现这一目标 Update 格雷格提出了关于可测试性的观点 由于 SqlObjects 将包含非常特定于业务流程的 sql
  • 如何计算最低系统要求?

    对于我用 Visual C 编写的应用程序 Testing 不 真的 这就是全部
  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • .NET 中是否有内置函数可以对密码进行哈希处理?

    我看到这个问题加密 散列数据库中的纯文本密码 https stackoverflow com questions 287517 encrypting hashing plain text passwords in database 我知道我
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect

随机推荐

  • 使用 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