【问题标题】:dynamic vs object keyword on method params and return type方法参数和返回类型上的动态 vs 对象关键字
【发布时间】:2015-04-03 05:36:42
【问题描述】:

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

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

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

虽然实际上我没有这样的方法签名,但为了简洁起见,此示例简化了两件事:方法参数中的“动态 vs 对象”关键字和返回值。

这两种方法有什么区别,它会产生相同的 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);
}

实体不是具体的,entityName 在 db 列中定义。我还考虑使用IEnumerableIEnumerable<dynamic>。有什么想法吗?

【问题讨论】:

标签: c# c#-4.0 dynamic


【解决方案1】:

取决于{... },它们肯定不会导致相同的 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 案例中缓慢而复杂的代码可能是我们真正想要的,而不是总是调用相同的重载。

【讨论】:

  • 问题是关于方法签名,而不是关于方法使用。
【解决方案2】:

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属性添加到返回和第一个参数中。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 2011-07-28
    • 2013-11-12
    • 1970-01-01
    • 2012-05-04
    相关资源
    最近更新 更多