方法参数和返回类型的动态vs对象关键字

一个非常基本的问题,请考虑以下方法:

public object Foo(object bar) {... } 

VS

 public dynamic Bar(dynamic bar) {... } 

虽然实际上我没有像这样的方法签名,但为了简洁起见,这个例子简化了两个方面:方法参数和return的’dynamic vs object’关键字。

这两种方法有什么区别,它会产生相同的IL还是会产生任何性能影响?

基于参考/工作/示例,告诉动态就像添加了动态特性的对象一样,我想两者都是相同的东西,但只是根据使用情况而有所不同,就像我想在返回值上添加另一个动态属性/方法一样。 但是我仍然想知道是否还有其他重要的事情需要考虑。

请注意,如果我有一个具有上述Bar方法的类并使用如下方法签名实现接口(反之亦然),则编译器不会抱怨任何内容。

 object Bar(object bar); 

经过大约3年的存在,我才有机会在项目中使用动态function,例如创建动态存储库以供Web API使用并生成(动态)JSON。

 public interface IRepository { IEnumerable GetAll(string entityName, int skip, int take); int Count(string entityName); dynamic GetById(string entityName, int key); void Add(string entityName, dynamic entity); void Remove(string entityName, int key); } 

如果实体不具体,则在db列中定义entityName 。 我还考虑使用IEnumerableIEnumerable 。 任何想法?

C#中的dynamic被转换为IL中的object

 .method private hidebysig instance object Foo(object bar) cil managed {...} .method private hidebysig instance object Bar(object bar) cil managed { .param [0] .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) .param [1] .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) ... } 

签名保持不变,只有Dynamic属性被添加到return和first参数中。

如果您可以将参数类型从dynamic更改为object而不必更改任何其他代码,请执行此操作。

取决于{... }他们肯定不会导致相同的IL! 考虑:

 public object Foo(object bar) { Use(bar); } void Use(int i) { } void Use(string s) { } void Use(IConvertible c) { } void Use(IEnumerable e) { } void Use(object o) { } 

IL将只包含对Use的最后一次重载的调用。

但是如果参数被声明为dynamic bar ,则IL将包含启动非常复杂的重载决策算法的代码。 这可能导致调用任何重载,或者可能导致错误(例如,使用bar==null ,无法确定最佳过载)。

显然非常不同的IL。 显然,当我们必须在应用程序运行时( dynamic )执行整个绑定时,性能会更糟,而不是在编译程序时一劳永逸地执行。

很明显, dynamic情况下缓慢而复杂的代码可能是我们真正想要的,而不是总是调用相同的重载。