扩展方法如何在内部工作? [英] How the extension methods working internally?

查看:124
本文介绍了扩展方法如何在内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个扩展方法因此,该类是静态的,该方法也是静态的!
问题是,CLR如何在没有类名的情况下将扩展调用绑定到扩展方法? (通常,如果类是静态的并且方法是静态的,我们可以使用类名来调用.这里我们没有指定类名.)

I am creating one extension method So ,the class is static and the method also static !!
question is that ,How the CLR binding the extension call to the extension method, without the class name??
(Normally if the class is static and method is static we can call by using the class name..Here we are not specifying the class name..)

public static class Exte
   {
       public static string GetFirstThreeCh(this string str)
       {
           if (str.Length < 3)
           {
               return str;
           }
           else
           {
               return str.Substring(0, 3);
           }
       }
   }





static void Main(string[] args)
     {
         String str = "my new String";
         
         str = str.GetFirstThreeCh();
     }

推荐答案

没有任何内部"内容.扩展方法在"SLR之上"起作用,它们只是语法糖:
http://en.wikipedia.org/wiki/Syntactic_sugar [
There is nothing "internal" about it. The extension methods work "on top of SLR", they are just the syntactic sugar:
http://en.wikipedia.org/wiki/Syntactic_sugar[^].

The code of using of an extension method is strictly equivalent to the code of using a static method of extension class directly:

string sample = //...
sample = str.GetFirstThreeCh();

//same as if you called:
sample = Exte.GetFirstThreeCh(str);





此语法功能模仿实例方法静态方法的语法.

为了更好地理解,请参阅我过去的答案中关于实例和静态方法如何工作的解释:
什么使静态方法可访问? [





This syntactic feature mimics the syntax of instance method with a static method.

For better understanding, see also my explanation on how instance and static methods work, in my past answer:
What makes static methods accessible?[^].



By the way, in your sample method, you should also check up the argument for null, and, say, also return str, otherwise your method with throw exception at str.Length. In this case, I would consider this as a bug.

—SA


请在此处查看扩展方法 [ ^ ]定义等

现在做一些有趣的工作,在这项研究中,我使用 ILDasm ( C:\ Program Files \ Microsoft SDKs \ Windows \ v7.0A \ bin \ NETFX 4.0 Tools \ ildasm.exe 但这是我安装的VS)工具的一部分,它是VS安装的一部分.除了将类名Exte 更改为ExtensionMethodClass外,我使用与提供的OP相同的C#代码.

我生成程序并获取程序的exe,在这种情况下,它是ConsoleApplication24.exe(因为我将代码放在称为ConsoleApplication24的控制台应用程序中)进入ILDasm程序,ILDasm为ExtensionMethodClass 生成了以下IL代码我们在这里定义扩展方法.

Please see here for the extension method[^]definition and etc.

Now do bit of interesting work, in this research I use ILDasm(C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\ildasm.exe but this is for my installed VS) tool which comes as part of the VS installation. I use the same C# code as OP provided except change the class name Exte to ExtensionMethodClass.

I build the program and grab the exe of the program in this case it is ConsoleApplication24.exe (as I put the code in the console app which is called ConsoleApplication24.) into the ILDasm program and ILDasm generate following IL code for the ExtensionMethodClass class in here we define the extension method.

.class public abstract auto ansi sealed beforefieldinit ExtensionMethodClass
    extends [mscorlib]System.Object
{
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
    .method public hidebysig static string GetFirstThreeCh(string str) cil managed
    {
        .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
        .maxstack 3
        .locals init (
            [0] string str2,
            [1] bool flag)
        //removed all the code for clearity
    }

}



如果我们看一下上面的IL代码,我们可以看到,


  • ExtensionMethodClass 类已定义为抽象且密封的.
  • 在该类中,GetFirstThreeCh 方法已被编译为具有字符串类型参数的静态公共方法.请注意,这里没有我们在GetFirstThreeCh方法的C#代码中定义的对象.
  • 因此,很明显,此IL代码将扩展方法定义为与静态方法相同.


  • If we look into the IL code above, we can see,


    • ExtensionMethodClass class has been define as abstract and sealed.
    • Inside this class GetFirstThreeCh method has been compiled as static public method which has string type parameter. NOTE that in here there is no this which we define in the C# code in the GetFirstThreeCh method.
    • So it is clear more this IL code that extension method has been define as same as static method.
    • .method private hidebysig static void Main(string[] args) cil managed
      {
          .entrypoint
          .maxstack 1
          .locals init (
              [0] string str)
          L_0000: nop 
          L_0001: ldstr "my new String"
          L_0006: stloc.0 
          L_0007: ldloc.0 
          L_0008: call string ConsoleApplication24.ExtensionMethodClass::GetFirstThreeCh(string)
          L_000d: stloc.0 
          L_000e: ret 
      }



      从上面的L_0008标签中的IL代码中,我们可以看到GetFirstThreeCh 方法的调用方式与CLR调用静态方法相同.

      为了测试这一点,我使用如下所示的静态方法创建了一个小的静态类,



      From the above IL code in L_0008 label we can see that GetFirstThreeCh method has been call as same as CLR call static method.

      To test this I created a small static class with a static method as below,

      namespace ConsoleApplication24
      {
          class Program
          {
              static void Main(string[] args)
              {
                    TestStaticMethod.TestMethod();
              }
          }    
      
          public class TestStaticMethod 
          {
              public static void TestMethod() 
              {
              }
          }
      }


      构建此新程序后,我使用ILDasm程序反编译以生成如下所示的IL代码,


      After building this new program I decompiled using ILDasm program to generate the IL code which is as below,

      .method private hidebysig static void Main(string[] args) cil managed
      {
          .entrypoint
          .maxstack 8
          L_0000: nop 
          L_0001: call void ConsoleApplication24.TestStaticMethod::TestMethod()
          L_0006: nop 
          L_0007: ret 
      }



      因此,我们可以看到CLR在后台如何处理扩展方法.

      希望它能解释细节:)



      So we can see that how does CLR handle the extension method in behind the scene.

      Hope it explain the details :)


      这篇关于扩展方法如何在内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆