一个非常基本的问题,请考虑以下方法:
public object Foo(object bar) {... }
VS
public dynamic Bar(dynamic bar) {... }
虽然我实际上没有像这样的方法签名,但为了简洁起见,这个例子简化了两个方面:方法参数和return的'dynamic vs object'关键字。
这两种方法有什么区别,是产生相同的IL还是产生任何性能影响?
基于参考/工作/示例,告诉动态就像添加动态功能的对象一样,我猜两者都是一样的但只是根据使用情况而有所不同,如果我想添加另一个动态属性/关于返回值的方法。但是我仍然想知道是否还有其他重要的事情需要考虑。
请注意,如果我有一个具有上述Bar
方法的类并使用如下方法签名实现接口(反之亦然),则编译器不会抱怨任何内容。
object Bar(object bar);
在存在大约3年后,我才有机会在项目中使用动态功能,例如创建动态存储库以供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
。我还要考虑使用IEnumerable
或IEnumerable<dynamic>
。有什么想法?
答案 0 :(得分:2)
根据{... }
,他们肯定不会导致相同的IL!考虑:
public object Foo(object bar)
{
Use(bar);
}
void Use(int i)
{
}
void Use(string s)
{
}
void Use(IConvertible c)
{
}
void Use<T>(IEnumerable<T> e)
{
}
void Use(object o)
{
}
IL只会调用Use
的最后一次重载。
但是如果参数被声明为dynamic bar
,IL将包含启动非常复杂的重载决策算法的代码。这可能导致调用任何重载,或者可能导致错误(例如,使用bar==null
,无法确定最佳过载。)
显然非常不同的IL。显然,当应用程序运行时(dynamic
)必须执行整个绑定时,性能会更差,而不是在编译程序时一劳永逸地执行它。
很明显dynamic
案例中缓慢而复杂的代码可能是我们真正想要的,而不是总是调用相同的重载。
答案 1 :(得分:0)
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
而无需更改任何其他代码,请执行此操作。