如何从动态对象中进行投射在C#中工作

时间:2017-01-03 11:30:04

标签: c# .net azure azure-cosmosdb

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

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

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

有人可以向我解释一下C#如何知道如何将动态对象转换为SalesOrder类的这个对象?我尝试过这种天真的方法,但它不起作用:

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

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

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

1 个答案:

答案 0 :(得分:5)

您的代码......

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

...不起作用,不是因为dynamic的中间转换,而是因为您的匿名类与SampleClass之间的类型不匹配。

不要将dynamic与匿名类混淆。没有dynamic类型的对象,它主要是just there for the compiler。另一方面,匿名类是在编译时存在的完整类型安全类。除非您不知道名称,否则非匿名类没有区别。编译器将在底层创建一个完整的类定义(使用反编译器进行检查)。

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

始终牢记C#是强类型的。在像JavaScript这样的弱类型语言中,你的任务就可以了。在C#中不是这样。

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

你的任务......

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

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