2012-05-24 14 views
2

我的代码中有一个操作方法如下:为什么我的外部C#函数的参数列表中存在“this”?

catch (Exception e) 
    { 
     log(e); 
     return Content(ExceptionExtensions.GetFormattedErrorMessage(e)); 
    } 

的函数调用看起来像这样:

public static class ExceptionExtensions 
{ 
    public static string GetFormattedErrorMessage(this Exception e) 

      if (e == null) 
     { 
      throw new ArgumentNullException("e"); 
     } 

有人能解释为什么有一个“本”在参数列表的开始?

回答

8

这是扩展方法的签名。它们是在.NET3.5(C#3)中引入的。如果没有this,编译器会将其作为静态方法签名。 下面的代码:

public class Foo 
{ 
    public void FooBar() 
    { 

    } 
} 
public static class FooEx 
{ 
    public static void Bar(this Foo f) 
    { 
     f.FooBar(); 
    } 
    public static void StaticBar(Foo f) 
    { 
     f.FooBar(); 
    } 
} 

你可以这样调用静态方法:

FooEx.StaticBar(new Foo()); 

和扩展方法是这样的:

new Foo().Bar(); 

和扩展方法为静态方法:

FooBar.Bar(new Foo()); 

因此,要将扩展方法转换为静态方法,您只需从签名中删除this关键字。 但是,如果你想一个静态方法转换成一个扩展方法,你必须:

  1. this关键字添加到签名
  2. 把方法变成非嵌套public static
  3. 充分利用该方法public

Scott Hanselman has a good article对语法的选择,以及如何访问修饰符它符合现有的CLR以最小的改动编译器。

总之,他得出结论,在编译之后,生成的静态方法的IL代码和扩展方法的代码没有区别。 关键字this指示编译器将某些元数据放在扩展方法的周围。

我的猜测是,他们已经为this关键字了,因为1.it已经存在,并且2.它的现有含义与其他现有关键字相比,最适合扩展方法的上下文。

+1

也许增加一些OP可以这样调用函数的东西:'e.GetFormattedErrorMessage()'。 – Marlon

+0

对不起,如果这听起来像一个愚蠢的问题,但你能猜出它为什么这样编码的任何原因。此外,如果我想将其改为静态方法,我怎么能这样做,哪些是劣势? –

+0

@SamanthaJ扩展方法*是*静态方法,它们可以使用正常的静态方法语法或扩展方法(准实例方法)语法来调用。出于这个原因,我相信,目前的例子不会编译,虽然我没有编译器方便检查。 – phoog

-1

“this”是传递给Exception方法的错误,类似于在函数中使用“this”。它只是指正在通过的例外。

+0

-1:不,“'this'”是传递给'GetFormattedErrorMessage'扩展方法的'Exception'。 –

2

因为这就是你如何定义'扩展'方法。它可以让编译器知道这个特定的方法应该被允许直接在对象上调用,它可以让你写这样的代码:

GetFormattedErrorMessage(e); 

,而不是为:

e.GetFormattedErrorMessage(); 

我不知道为什么你发布的代码是以这种方式调用函数。你应该能够直接在异常对象上调用该函数。扩展方法本质上就是扩展你以前无法修改的内置类/类型的行为的方法。

相关问题