DynamicMethod.TryInvokeMember() 相对于使用字典作为参数的优点?
有哪些优点
DynamicObject.TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
在 C# 4.0 中(除了语法之外)使用此签名比仅调用非动态方法
public object MethodParser(string methodName, Dictionary<string, object> arguments)
:其中 methodName 是“方法”的名称,参数是参数名称和参数值的字典(MethodParser 是只是一个任意的名字)
换句话说,
foo.NonExistentMethod(arg1:"a1", arg2:3.14m)
调用
foo.MethodParser("NonExistentMethod", new Dictionary<string, object>(){{"arg1", "a1"}, {"arg2": 3.14m}})
What are the advantages in C# 4.0 (besides syntax) of using
DynamicObject.TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
over just calling a non-dynamic method with this signature:
public object MethodParser(string methodName, Dictionary<string, object> arguments)
where methodName is the name of the "method" arguments is a dictionary of the argument name and the argument value (MethodParser is just an arbitrary name)
In other words, calling
foo.NonExistentMethod(arg1:"a1", arg2:3.14m)
over
foo.MethodParser("NonExistentMethod", new Dictionary<string, object>(){{"arg1", "a1"}, {"arg2": 3.14m}})
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以更轻松地调整性能,而无需在 DynamicObject 外部进行重构。例如,如果在分析时发现该对象上的特定动态方法调用是热点,则可以在 DynamicObject 上静态添加该特定方法,不仅会获得非字符串查找动态调用(在第一个方法之后)调用),但是您可以以干净的方式与动态代码的其余部分分开来优化您的特定实现。
或者,您可以为整个动态代码编写一个更优化的 IDynamicMetaObjectProvider,而不是使用 DynamicObject(就像 Microsoft 对 ExpandoObject 所做的那样),然后它就不需要像
MethodParser
那样依赖于每个后续调用的字符串查找和 TryInvokeMember 会。如果成员名并不是真正重要,那么很难从示例中看出,您可以仅静态声明属性 getter,使用
DynamicObject.TryInvoke
与 DynamicObject 返回动态,然后您将获得一些自动完成功能名称部分,并且仍然可以具有动态参数名称。但显然,我们应该忽视的主要优点是
MethodParser
的可读性要差得多。You have more ability to easily performance tune without refactoring outside of the DynamicObject. For example, if while profiling you find that a specific dynamic method call on that object is a hotspot, you can just add that specific method statically on your DynamicObject, not only do you get a non-string-lookup dynamic call (after the first call), but you can then optimize your specific implementation separate from the rest of your dynamic code in a clean fashion.
Or you can just write a more optimized IDynamicMetaObjectProvider for your entire dynamic code rather than using DynamicObject (like Microsoft did for ExpandoObject) and then it wouldn't need to rely on string lookup for each subsequent invocation like
MethodParser
andTryInvokeMember
would.If the membername isn't really the important, it's hard to tell from the example you could just statically declare property getters that return dynamic with a DynamicObject using
DynamicObject.TryInvoke
and then you'll get some autocomplete for the name portion and can still have dynamic argument names.But obviously the main advantage, is the one we are supposed to discount, is that
MethodParser
is much less readable.动态方法的优点是它们可以提供与动态语言的互操作性,特别是那些由 DLR、IronPython 和 IronRuby 提供的语言。您提出的第二种方法不提供任何互操作性。
可读性的另一个巨大优势。审查和维护代码的人可以比基于字典的调用更容易地阅读和理解动态方法调用。
The advantages of dynamic methods are that they can provide interoperability with dynamic languages, particularly those provided by the DLR, IronPython and IronRuby. The second method you proposed does not provide any interoperability.
Another huge advantage of readability. Someone reviewing and maintaining the code can read and understand the dynamic method call much easier than the dictionary based call.
这是一个大问题。以下是我对这个主题的一些想法。
优点
1)VS可以为以前使用过的动态成员提供智能,这是更好的IDE体验。
2)与其他代码更加一致,更容易阅读和理解。
3) 它可以更好地执行,因为它是反射之上的一层,因此可以缓存委托,从而只为成员调用一次反射。
4) 它可以与 COM 等技术进行互操作,而使用反射时则不然,并且避免了在调用之间显式转换类型的需要。
5) 与
Reflection
相比,它提供了更松散的耦合。可以重新映射内部成员而不影响使用它的代码。6) 可以虚拟化实例。被调用的成员实际上不需要存在。该实现是完全可扩展的,并允许创建对调用者隐藏实现的代理/外观。
缺点
1)在类型检查不必要地丢失的情况下容易被滥用。就像输入关键字与理解并围绕
Reflection
编写代码一样简单。2)使用良好的语法不可能防止魔术字符串。
我确信还有更多只是想分享一些尚未提出的观点。
That's a big question. Here are some thoughts I have on the subject.
Advantages
1) VS can provide intellisence for previously used dynamic members, which is a better IDE experience.
2) It's more consistent with other code, making it more easy to read and understand.
3) It can perform better because it's a layer on top of
Reflection
, and can therefore cache delegates, thereby only invokingReflection
once for a member.4) It's interoperable with technologies such as COM, which isn't true when using
Reflection
, and avoids the need to explicitly cast types between the calls.5) It provides looser coupling than with
Reflection
. It's possible to remap inner members without affecting the code that consumes it.6) It's possible to virtualise an instance. The members called don't actually need to exist. The implementation is entirely extendable and allows for the creation of proxies/facades which hide implementations from the caller.
Disadvantages
1) Easily abused in scenarios where type checking is unnecessarily lost. It's as simple as typing a keyword vs understanding and writing code around
Reflection
.2) Using the nice syntax it's not possible to protect against magic strings.
I'm sure there's more just wanted to share some points that hadn't been raised.