简体   繁体   English

动态朗。运行时与反射

[英]Dynamic Lang. Runtime vs Reflection

I am planning to use dynamic keyword for my new project. 我打算为我的新项目使用动态关键字。 But before stepping in, I would like to know about the pros and cons in using dynamic keyword over Reflection. 但在介入之前,我想了解使用动态关键字而不是反射的优缺点。

Following where the pros, I could find in respect to dynamic keyword: 在专业人士的位置,我可以找到关于动态关键字:

  • Readable\\Maintainable code. 可读\\可维护代码。
  • Fewer lines of code. 更少的代码行。

While the negatives associated with using dynamic keyword, I came to hear was like: 虽然与使用动态关键字相关的负面因素,我听到的是:

  • Affects application performance. 影响应用程序性能。
  • Dynamic keyword is internally a wrapper of Reflection. Dynamic关键字在内部是Reflection的包装器。
  • Dynamic typing might turn into breeding ground for hard to find bugs. 动态类型可能会成为难以找到错误的滋生地。
  • Affects interoperability with previous .NET versions. 影响与以前的.NET版本的互操作性。

Please help me on whether the pros and cons I came across are sensible or not? 请帮助我看看我遇到的利弊是否合情合理?

Please help me on whether the pros and cons I came across are sensible or not? 请帮助我看看我遇到的利弊是否合情合理?

The concern I have with your pros and cons is that some of them do not address differences between using reflection and using dynamic. 我对你的优点和缺点的关注是,其中一些没有解决使用反射和使用动态之间的差异。 That dynamic typing makes for bugs that are not caught until runtime is true of any dynamic typing system. 这种动态类型会导致在任何动态类型系统的运行时都没有捕获的错误。 Reflection code is just as likely to have a bug as code that uses the dynamic type. 反射代码与使用动态类型的代码一样容易出错。

Rather than thinking of it in terms of pros and cons, think about it in more neutral terms. 不要在利弊方面考虑它,而是以更中性的方式思考它。 The question I'd ask is "What are the differences between using Reflection and using the dynamic type?" 我要问的问题是“使用Reflection和使用动态类型有什么区别 ?”

First: with Reflection you get exactly what you asked for. 第一:与反思你得到你问什么了。 With dynamic, you get what the C# compiler would have done had it been given the type information at compile time . 使用动态,您可以获得C#编译器在编译时获得类型信息时所做的事情 Those are potentially two completely different things. 这些可能是两个完全不同的东西。 If you have a MethodInfo to a particular method, and you invoke that method with a particular argument, then that is the method that gets invoked , period. 如果您有一个特定方法的MethodInfo,并且您使用特定参数调用该方法,那么这是被调用的方法 ,句点。 If you use "dynamic", then you are asking the DLR to work out at runtime what the C# compiler's opinion is about which is the right method to call. 如果你使用“动态”,那么你要求DLR在运行时解决C#编译器关于哪种方法是正确调用的意见。 The C# compiler might pick a method different than the one you actually wanted. C#编译器可能会选择与您实际需要的方法不同的方法。

Second: with Reflection you can (if your code is granted suitably high levels of trust) do private reflection. 第二:使用Reflection,您可以(如果您的代码被授予适当的高度信任)进行私人反思。 You can invoke private methods, read private fields, and so on. 您可以调用私有方法,读取私有字段等。 Whether doing so is a good idea, I don't know. 这样做是不是一个好主意,我不知道。 It certainly seems dangerous and foolish to me, but I don't know what your application is. 这对我来说当然是危险和愚蠢的,但我不知道你的申请是什么。 With dynamic, you get the behaviour that you'd get from the C# compiler; 使用动态,您将获得从C#编译器获得的行为; private methods and fields are not visible. 私有方法和字段不可见。

Third: with Reflection, the code you write looks like a mechanism . 第三:使用Reflection,您编写的代码看起来像一种机制 It looks like you are loading a metadata source, extracting some types, extracting some method infos, and invoking methods on receiver objects through the method info. 看起来您正在加载元数据源,提取某些类型,提取一些方法信息,以及通过方法信息调用接收器对象上的方法。 Every step of the way looks like the operation of a mechanism . 该方式的每一步都看起来像一个机制的操作。 With dynamic, every step of the way looks like business logic . 通过动态,每一步都看起来像业务逻辑 You invoke a method on a receiver the same way as you'd do it in any other code. 您在接收器上调用方法的方式与在任何其他代码中执行方法相同。 What is important? 什么是重要的? In some code, the mechanism is actually the most important thing. 在某些代码中,该机制实际上是最重要的。 In some code, the business logic that the mechanism implements is the most important thing. 在某些代码中,机制实现的业务逻辑是最重要的。 Choose the technique that emphasises the right level of abstraction. 选择强调正确抽象级别的技术。

Fourth: the performance costs are different. 第四:绩效成本不同。 With Reflection you do not get any cached behaviour, which means that operations are generally slower, but there is no memory cost for maintaining the cache and every operation is roughly the same cost. 使用Reflection,您不会获得任何缓存行为,这意味着操作通常较慢,但维护缓存没有内存成本,并且每个操作的成本大致相同。 With the DLR, the first operation is very slow indeed as it does a huge amount of analysis, but the analysis is cached and reused. 使用DLR,第一次操作确实非常慢,因为它进行了大量的分析,但是分析被缓存并重用。 That consumes memory, in exchange for increased speed in subsequent calls in some scenarios. 这会消耗内存,以换取在某些情况下后续调用中增加的速度。 What the right balance of speed and memory usage is for your application, I don't know. 我不知道你的应用程序的速度和内存使用的正确平衡是什么。

Readable\\Maintainable code 可读\\可维护代码

Certainly true in my experence. 我的经历当然是对的。

Fewer lines of code. 更少的代码行。

Not significantly, but it will help. 不显着,但它会有所帮助。

Affects application performance. 影响应用程序性能。

Very slightly. 非常轻微。 But not even close to the way reflection does. 但是,甚至没有接近反射的方式。

Dynamic keyword is internally a wrapper of Reflection. Dynamic关键字在内部是Reflection的包装器。

Completely untrue. 完全不真实。 The dynamic keyword leverages the Dynamic Library Runtime. 动态关键字利用动态库运行时。

[Edit: correction as per comment below] [编辑:根据以下评论进行修正]

It would seem that the Dynamic Language Runtime does use Reflection and the performance improvements are only due to cacheing techniques. 似乎动态语言运行时确实使用了Reflection,性能改进只是由于缓存技术。

Dynamic typing might turn into breeding ground for hard to find bugs. 动态类型可能会成为难以找到错误的滋生地。

This may be true; 这可能是真的; it depends how you write your code. 这取决于你如何编写代码。 You are effectively removing compiler checking from your code. 您正在有效地从代码中删除编译器检查。 If your test coverage is good, this probably won't matter; 如果您的测试覆盖率良好,这可能无关紧要; if not then I suspect you will run into problems. 如果没有,那么我怀疑你会遇到问题。

Affects interoperability with previous .NET versions 影响与以前的.NET版本的互操作性

Not true. 不对。 I mean you won't be able to compile your code against older versions, but if you want to do that then you should use the old versions as a base and up-compile it rather than the other way around. 我的意思是你将无法针对旧版本编译你的代码,但如果你想这样做,那么你应该使用旧版本作为基础并上传它而不是相反。 But if you want to use a .NET 2 library then you shouldn't run into too many problems, as long as you include the declaration in app.config / web.config. 但是,如果您想使用.NET 2库,那么只要在app.config / web.config中包含声明,就不应该遇到太多问题。

One significant pro that you're missing is the improved interoperability with COM/ATL components. 您缺少的一个重要项目是改进了与COM / ATL组件的互操作性。

There are 4 great differences between Dynamic and reflection. 动态和反射之间有4个很大的区别。 Below is a detailed explanation of the same. 以下是对其的详细说明。 Reference http://www.codeproject.com/Articles/593881/What-is-the-difference-between-Reflection-and-Dyna 参考http://www.codeproject.com/Articles/593881/What-is-the-difference-between-Reflection-and-Dyna

Point 1. Inspect VS Invoke 第1点。检查VS Invoke

Reflection can do two things one is it can inspect meta-data and second it also has the ability to invoke methods on runtime.While in Dynamic we can only invoke methods. 反射可以做两件事,一件是它可以检查元数据,二是它还具有在运行时调用方法的能力。而在Dynamic中,我们只能调用方法。 So if i am creating software's like visual studio IDE then reflection is the way to go. 因此,如果我正在创建像visual studio IDE这样的软件,那么反射就是最佳选择。 If i just want dynamic invocation from the my c# code, dynamic is the best option. 如果我只想从我的c#代码动态调用,动态是最好的选择。

DynamicVsReflection

Point 2. Private Vs Public Invoke Point 2. Private Vs Public Invoke

You can not invoke private methods using dynamic. 您无法使用动态调用私有方法。 In reflection its possible to invoke private methods. 在反射中,它可以调用私有方法。

Point 3. Caching 第3点。缓存

Dynamic uses reflection internally and it also adds caching benefits. Dynamic在内部使用反射,它还增加了缓存优势。 So if you want to just invoke a object dynamically then Dynamic is the best as you get performance benefits. 因此,如果您只想动态调用一个对象,那么动态是最好的,因为您可以获得性能优势。

Point 4. Static classes 第4点。静态类

Dynamic is instance specific: You don't have access to static members; 动态是特定于实例的:您无权访问静态成员; you have to use Reflection in those scenarios. 你必须在这些场景中使用Reflection。

In most cases, using the dynamic keyword will not result in meaningfully shorter code. 在大多数情况下,使用dynamic关键字不会导致有意义的更短代码。 In some cases it will; 在某些情况下,它会; that depends on the provider and as such it's an important distinction. 这取决于提供商,因此这是一个重要的区别。 You should probably never use the dynamic keyword to access plain CLR objects; 您可能永远不应该使用dynamic关键字来访问纯CLR对象; the benefit there is too small. 这个好处太小了。

The dynamic keyword undermines automatic refactoring tools and makes high-coverage unit tests more important; 动态关键字破坏了自动重构工具,使高覆盖率的单元测试变得更加重要; after all, the compiler isn't checking much of anything when you use it. 毕竟,当你使用它时,编译器没有检查任何东西。 That's not as much of an issue when you're interoperating with a very stable or inherently dynamically typed API, but it's particularly nasty if you use keyword dynamic to access a library whose API might change in the future (such as any code you yourself write). 当您使用非常稳定或固有动态类型的API进行互操作时,这并不是一个问题,但如果您使用关键字动态来访问其API可能在将来发生变化的库(例如您自己编写的任何代码),那么这一点尤其令人讨厌)。

Use the keyword sparingly, where it makes sense, and make sure such code has ample unit tests. 在有意义的地方谨慎使用关键字,并确保此类代码具有充足的单元测试。 Don't use it where it's not needed or where type inference (eg var ) can do the same. 不要在不需要它或类型推断(例如var )可以做同样的地方使用它。

Edit: You mention below that you're doing this for plug-ins. 编辑:您在下面提到您正在为插件执行此操作。 The Managed Extensibility Framework was designed with this in mind - it may be a better option that keyword dynamic and reflection. 托管可扩展性框架的设计考虑到了这一点 - 关键字dynamic和反射可能是更好的选择。

If you are using dynamic specifically to do reflection your only concern is compatibility with previous versions. 如果您使用动态专门进行反射,那么您唯一关心的是与先前版本的兼容性。 Otherwise it wins over reflection because it is more readable and shorter. 否则它会胜过反思,因为它更具可读性和更短。 You will lose strong typing and (some) performance from the very use of reflection anyway. 无论如何,你将失去强烈的打字和(某些)表现。

The way I see it all your cons for using dynamic except interoperability with older .NET versions are also present when using Reflection: 我在使用Reflection时也会看到使用动态的所有缺点,除了与旧.NET版本的互操作性之外:

Affects application performance 影响应用程序性能

While it does affect the performance, so does using Reflection. 虽然它确实影响了性能,但使用Reflection也是如此。 From what I remember the DLR more or less uses Reflection the first time you access a method/property of your dynamic object for a given type and caches the type/access target pair so that later access is just a lookup in the cache making it faster then Reflection 从我记得DLR或多或少使用Reflection第一次访问给定类型的动态对象的方法/属性并缓存类型/访问目标对,以便以后访问只是在缓存中查找,使其更快然后反思

Dynamic keyword is internally a wrapper of Reflection Dynamic关键字在内部是Reflection的包装器

Even if it was true (see above), how would that be a negative point? 即使这是真的(见上文),这将是一个负面因素? Whether or not it does wrap Reflection shouldn't influence your application in any significant matter. 它是否包装反射不应影响您在任何重要事项中的应用。

Dynamic typing might turn into breeding ground for hard to find bugs 动态类型可能会成为难以找到错误的滋生地

While this is true, as long as you use it sparingly it shouldn't be that much of a problem. 虽然这是事实,但只要你谨慎使用它就不应该是一个问题。 Furthermore is you basically use it as a replacement for reflection (that is you use dynamic only for the briefest possible durations when you want to access something via reflection), the risk of such bugs shouldn't be significantly higher then if you use reflection to access your methods/properties (of course if you make everything dynamic it can be more of a problem). 此外,你基本上用它作为反射的替代品(也就是说,当你想通过反射访问某些东西时,你只使用动态的最短时间),这种错误的风险不应该高得多,如果你使用反射来访问你的方法/属性(当然,如果你把一切都变得动态,它可能会更成问题)。

Affects interoperability with previous .NET versions 影响与以前的.NET版本的互操作性

For that you have to decide yourself how much of a concern it is for you. 为此,你必须自己决定对你有多大关注。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM