我计划在我的新项目中使用动态关键字。但是在开始之前,我想了解使用动态关键字而不是反射的优缺点。
以下是我在使用动态关键字方面找到的优点:
- 易读易维护的代码。
- 代码行数更少。
然而,使用动态关键字可能带来的负面影响包括:
- 影响应用程序性能。
- 动态关键字在内部是反射的一个包装器。
- 动态类型可能会成为难以发现错误的温床。
- 影响与之前的.NET版本的互操作性。
请帮我确认一下我找到的优缺点是否合理?
我计划在我的新项目中使用动态关键字。但是在开始之前,我想了解使用动态关键字而不是反射的优缺点。
以下是我在使用动态关键字方面找到的优点:
然而,使用动态关键字可能带来的负面影响包括:
请帮我确认一下我找到的优缺点是否合理?
第三点:使用反射时,你编写的代码看起来像一个机制。看起来你正在加载元数据源,提取一些类型、提取一些方法信息,并通过方法信息在接收对象上调用方法。每一步都像一个机制的操作。使用动态语言,每一步看起来像是业务逻辑。你以与其他任何代码相同的方式在接收器上调用方法。什么是重要的?在某些代码中,机制实际上是最重要的事情。在某些代码中,机制实现的业务逻辑是最重要的事情。选择强调正确抽象级别的技术。
第四点:性能成本是不同的。使用反射,您不会得到任何缓存行为,这意味着操作通常较慢,但不会有维护缓存的内存成本,每个操作的成本大致相同。使用DLR,第一次操作确实非常慢,因为它进行了大量分析,但分析被缓存和重复使用。这消耗了内存,换取某些场景下后续调用的速度增加。对于您的应用程序来说,速度和内存使用的正确平衡是什么,我不知道。
可读性好、易于维护的代码
从我的经验来看,这是确实的。
代码行数更少。
影响不大,但有所帮助。
影响应用程序的性能。
影响非常小,但与反射方式相比仍有很大差距。
动态关键字在内部是 Reflection 的包装器。
完全不正确。动态关键字利用了 Dynamic Library Runtime。
[编辑:根据下面的评论进行更正]
似乎 Dynamic Language Runtime 确实使用了反射,而性能改进只是由于缓存技术造成的。
动态数据类型可能会成为难以找到错误的温床。
这可能是真的;这取决于你如何编写你的代码。你实际上正在从你的代码中删除编译器检查。如果你的测试覆盖率很好,这可能不重要;如果不是,我认为你会遇到问题。
影响与之前的 .NET 版本的互操作性
不正确。我的意思是,你将无法针对旧版本编译你的代码,但如果你想这样做,那么你应该以旧版本为基础,并进行向上编译而不是相反。但如果你想使用 .NET 2 库,那么你不应该遇到太多问题,只要在 app.config / web.config 中包含声明即可。
你所忽略的一个显著优点是与 COM/ATL 组件的改进互操作性。
动态和反射之间有四个很大的区别。以下是详细的解释。参考http://www.codeproject.com/Articles/593881/What-is-the-difference-between-Reflection-and-Dyna
点1. 检查 VS 调用
反射可以做两件事情,一是检查元数据,二是在运行时调用方法。而在动态中我们只能调用方法。如果我正在创建像Visual Studio IDE这样的软件,那么反射是最好的选择。如果我只想从我的C#代码中进行动态调用,则动态是最好的选择。
点2. 私有 Vs 公共 方法调用
使用动态无法调用私有方法。在反射中可以调用私有方法。
点3. 缓存
动态在内部使用反射,并且它还提供了缓存的好处。所以,如果你只想动态调用对象,那么动态是最好的选择,因为它会带来性能上的优势。
点4. 静态类
动态是针对实例的:您无法访问静态成员;在这些情况下,您必须使用反射。
var
)的地方使用它。如果您使用动态编程来进行反射,那么您唯一需要考虑的是与先前版本的兼容性。否则,它比反射更易读且更短。无论如何,从使用反射开始,您都会失去强类型和(某些)性能。
就我的看法,在使用动态语言时,你提到的所有缺点,除了与旧版 .NET 兼容性之外,使用反射也存在:
影响应用程序性能
虽然它确实会影响性能,但使用反射也是如此。据我所记,DLR 在首次访问给定类型的动态对象的方法/属性时,更多或更少地使用反射,并缓存类型/访问目标对,以便以后的访问只是在缓存中进行查找,使其比反射更快。
Dynamic 关键字在内部是 Reflection 的包装器
即使这是真的(见上文),那也有什么负面影响呢?无论它是否包装了 Reflection 都不应对你的应用程序产生任何重大影响。
动态类型可能成为难以发现错误的滋生场所
虽然这是真的,但只要你谨慎使用,它就不应该成为太大的问题。此外,如果你基本上将其作为反射的替代品使用(也就是说,你只在最短的时间内使用 dynamic 来通过反射访问某些东西),那么这种错误的风险不应该比使用反射访问方法/属性时显著更高(当然,如果你把所有东西都变成动态的,可能会更成问题)。
影响与先前的.NET版本的互操作性。 对此,您必须自己决定这对您有多大的影响。