扩展方法性能

Kus*_*sek 8 .net-3.5 c#-3.0

            /*I have defined Extension Methods for the TypeX like this*/ 
        public static Int32 GetValueAsInt(this TypeX oValue)
        {
            return Int32.Parse(oValue.ToString());
        }
        public static Boolean GetValueAsBoolean(this TypeX oValue)
        {
            return Boolean.Parse(oValue.ToString());
        }


         TypeX x = new TypeX("1");
         TypeX y = new TypeX("true");


         //Method #1
         Int32 iXValue = x.GetValueAsInt();
         Boolean iYValue = y.GetValueAsBoolean();

         //Method #2
         Int32 iXValueDirect = Int32.Parse(x.ToString());
         Boolean iYValueDirect = Boolean.Parse(y.ToString());
Run Code Online (Sandbox Code Playgroud)

不要被TypeX带走,说我应该在TypeX中定义那些方法而不是扩展)我无法控制它(实际类我定义它在SPListItem上.

我想将TypeX转换为Int或Boolean,这个操作是我在代码中的很多Places中做的一件常见的事情.我想知道这会导致性能下降.我试图使用Reflector解释IL代码,但我并不擅长.可能对于上面的例子,不会有任何性能降低.总的来说,我想知道在使用Extension方法时对Regard对Performance的影响.

Jon*_*eet 25

扩展方法只是一个编译时改变:

x.GetValueAsBoolean()
Run Code Online (Sandbox Code Playgroud)

Extensions.GetValueAsBoolean(x)
Run Code Online (Sandbox Code Playgroud)

这就是所涉及的 - 将看起来像实例方法调用的内容转换为对静态方法的调用.

如果静态方法没有性能问题,那么将其作为扩展方法将不会引入任何新问题.

编辑:IL,按要求......

拿这个样本:

using System;

public static class Extensions
{
    public static void Dump(this string x)
    {
        Console.WriteLine(x);
    }
}

class Test
{
    static void Extension()
    {
        "test".Dump();
    }

    static void Normal()
    {
        Extensions.Dump("test");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是IL for ExtensionNormal:

.method private hidebysig static void  Extension() cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "test"
  IL_0006:  call       void Extensions::Dump(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Test::Extension

.method private hidebysig static void  Normal() cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "test"
  IL_0006:  call       void Extensions::Dump(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Test::Normal
Run Code Online (Sandbox Code Playgroud)

如你所见,它们完全一样.

  • 到目前为止,这个问题的最佳和最全面的答案 (2认同)
  • 山姆和乔恩,我不明白IL的例子.转储是我同意的扩展方法.Extension()和Normal()都做同样的事情.显然它有相同的IL (2认同)