从动态对象进行转换如何在 C# 中工作

How does casting from dynamic object works in C#

我在 DocumentDB 文档中找到了这段代码:

https://github.com/Azure/azure-documentdb-dotnet/blob/master/samples/code-samples/DocumentManagement/Program.cs#L173

SalesOrder readOrder = (SalesOrder)(dynamic)response.Resource;

谁能给我解释一下 C# 是如何知道如何将动态对象转换为 class SalesOrder 对象的?我已经尝试过这种天真的方法,但它不起作用:

class SampleClass { public string Name { get; set; } }

object o = new { Name = "test" };
SampleClass casted = (SampleClass)(dynamic)o; // this won't work

我需要做什么才能允许以与链接示例中相同的方式进行转换?

您的代码...

object o = new { Name = "test" };
SampleClass casted = (SampleClass)(dynamic)o; // this won't work

...不起作用,不是因为中间转换为 dynamic,而是因为您的匿名 class 和 SampleClass.[=25= 之间的类型不匹配]

不要将 dynamic 与匿名 class 混淆。没有dynamic类型的对象,主要是just there for the compiler。另一方面,匿名 classes 是编译时存在的完整 type-safe classes。与非匿名 classes 没有区别,只是你不知道名字。编译器将在幕后创建一个完整的 class 定义(用反编译器检查)。

这也是你作业的问题。您正在尝试将匿名 class 的对象分配给类型 SampleClass 的变量。这行不通(他们共享 Name 属性 并不重要)。您也可以尝试分配 stringint 或任何其他类型(SampleClass 除外),结果将完全相同。

永远记住 C# 是强类型的。在像 JavaScript 这样的弱类型语言中,你的任务是可行的。在 C# 中不是这样。

更新(包含问题评论中的信息):

你的作业...

SalesOrder readOrder = (SalesOrder)(dynamic)response.Resource;

...在一个重要方面有所不同。转换后的类型实现了 IDynamicMetaObjectProvider 接口。强制转换为 dynamic 使编译器识别此接口。然后它可以注入代码以使用该接口转换为 SalesOrder。它将导致完全不同的代码,这些代码将执行与常规类型转换无关的源对象的动态运行时转换。