<legend id='bNmbD'><style id='bNmbD'><dir id='bNmbD'><q id='bNmbD'></q></dir></style></legend>
    <bdo id='bNmbD'></bdo><ul id='bNmbD'></ul>
  • <i id='bNmbD'><tr id='bNmbD'><dt id='bNmbD'><q id='bNmbD'><span id='bNmbD'><b id='bNmbD'><form id='bNmbD'><ins id='bNmbD'></ins><ul id='bNmbD'></ul><sub id='bNmbD'></sub></form><legend id='bNmbD'></legend><bdo id='bNmbD'><pre id='bNmbD'><center id='bNmbD'></center></pre></bdo></b><th id='bNmbD'></th></span></q></dt></tr></i><div id='bNmbD'><tfoot id='bNmbD'></tfoot><dl id='bNmbD'><fieldset id='bNmbD'></fieldset></dl></div>

      1. <small id='bNmbD'></small><noframes id='bNmbD'>

        <tfoot id='bNmbD'></tfoot>

        调用和动态调用之间的区别

        时间:2023-11-11
        • <bdo id='NhQuL'></bdo><ul id='NhQuL'></ul>

              • <small id='NhQuL'></small><noframes id='NhQuL'>

                1. <tfoot id='NhQuL'></tfoot>
                    <tbody id='NhQuL'></tbody>

                  <i id='NhQuL'><tr id='NhQuL'><dt id='NhQuL'><q id='NhQuL'><span id='NhQuL'><b id='NhQuL'><form id='NhQuL'><ins id='NhQuL'></ins><ul id='NhQuL'></ul><sub id='NhQuL'></sub></form><legend id='NhQuL'></legend><bdo id='NhQuL'><pre id='NhQuL'><center id='NhQuL'></center></pre></bdo></b><th id='NhQuL'></th></span></q></dt></tr></i><div id='NhQuL'><tfoot id='NhQuL'></tfoot><dl id='NhQuL'><fieldset id='NhQuL'></fieldset></dl></div>
                  <legend id='NhQuL'><style id='NhQuL'><dir id='NhQuL'><q id='NhQuL'></q></dir></style></legend>

                  本文介绍了调用和动态调用之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  委托中的 Invoke 和 DynamicInvoke 有什么区别?请给我一些代码示例来解释这两种方法之间的区别.

                  What is the difference between Invoke and DynamicInvoke in delegates? Please give me some code example which explain difference between that two methods.

                  推荐答案

                  当你有一个委托实例时,你可能知道确切的类型,或者你可能只知道它是一个 Delegate.如果您知道确切的类型,则可以使用 Invoke,它非常快 - 一切都已预先验证.例如:

                  When you have a delegate instance, you might know the exact type, or you might just know that it is a Delegate. If you know the exact type, you can use Invoke, which is very fast - everything is already pre-validated. For example:

                  Func<int,int> twice = x => x * 2;
                  int i = 3;
                  int j = twice.Invoke(i);
                  // or just:
                  int j = twice(i);
                  

                  但是!如果你只知道它是 Delegate,它必须手动解析参数等 - 这可能涉及拆箱等 - 很多反思正在进行.例如:

                  However! If you just know that it is Delegate, it has to resolve the parameters etc manually - this might involve unboxing, etc - a lot of reflection is going on. For example:

                  Delegate slowTwice = twice; // this is still the same delegate instance
                  object[] args = { i };
                  object result = slowTwice.DynamicInvoke(args);
                  

                  请注意,我写了 args 长手,以明确涉及到 object[].这里有很多额外的费用:

                  Note I've written the args long hand to make it clear that an object[] is involved. There are lots of extra costs here:

                  • 数组
                  • 验证传递的参数是否适合实际的 MethodInfo
                  • 根据需要拆箱等
                  • 反射调用
                  • 那么调用者需要做一些事情来处理返回值

                  基本上,尽可能避免 DynamicInvoke.Invoke 总是更可取的,除非你只有一个 Delegate 和一个 object[].

                  Basically, avoid DynamicInvoke when-ever you can. Invoke is always preferable, unless all you have is a Delegate and an object[].

                  为了进行性能比较,在调试器(控制台 exe)之外的发布模式下打印以下内容:

                  For a performance comparison, the following in release mode outside of the debugger (a console exe) prints:

                  Invoke: 19ms
                  DynamicInvoke: 3813ms
                  

                  代码:

                  Func<int,int> twice = x => x * 2;
                  const int LOOP = 5000000; // 5M
                  var watch = Stopwatch.StartNew();
                  for (int i = 0; i < LOOP; i++)
                  {
                      twice.Invoke(3);
                  }
                  watch.Stop();
                  Console.WriteLine("Invoke: {0}ms", watch.ElapsedMilliseconds);
                  watch = Stopwatch.StartNew();
                  for (int i = 0; i < LOOP; i++)
                  {
                      twice.DynamicInvoke(3);
                  }
                  watch.Stop();
                  Console.WriteLine("DynamicInvoke: {0}ms", watch.ElapsedMilliseconds);
                  

                  这篇关于调用和动态调用之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:Func vs. Action vs. Predicate 下一篇:当作为普通委托参数提供时,为什么必须强制转换 lambda 表达式

                  相关文章

                  <small id='vFf5l'></small><noframes id='vFf5l'>

                  <i id='vFf5l'><tr id='vFf5l'><dt id='vFf5l'><q id='vFf5l'><span id='vFf5l'><b id='vFf5l'><form id='vFf5l'><ins id='vFf5l'></ins><ul id='vFf5l'></ul><sub id='vFf5l'></sub></form><legend id='vFf5l'></legend><bdo id='vFf5l'><pre id='vFf5l'><center id='vFf5l'></center></pre></bdo></b><th id='vFf5l'></th></span></q></dt></tr></i><div id='vFf5l'><tfoot id='vFf5l'></tfoot><dl id='vFf5l'><fieldset id='vFf5l'></fieldset></dl></div>
                  <tfoot id='vFf5l'></tfoot>

                      <bdo id='vFf5l'></bdo><ul id='vFf5l'></ul>
                    <legend id='vFf5l'><style id='vFf5l'><dir id='vFf5l'><q id='vFf5l'></q></dir></style></legend>