2

我的代码在操作方法中有以下内容:

    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");
        }

有人可以解释为什么参数列表的开头有一个“this”吗?

4

4 回答 4

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 有一篇很好的文章,介绍了语法的选择以及它如何适应现有的 CLR,只需对编译器进行最小的更改。

综上所述,他得出的结论是,编译后生成的静态方法的 IL 代码和扩展方法的代码没有区别。关键字用于指示编译器在this扩展方法周围放置一些元数据。

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

于 2012-05-24T03:02:59.183 回答
2

因为这就是您定义“扩展”方法的方式。它让编译器知道应该允许直接在对象上调用此特定方法,它让您可以编写如下代码:

GetFormattedErrorMessage(e);

而不是:

e.GetFormattedErrorMessage();

我不确定您发布的代码为什么以这种方式调用该函数。您应该能够直接在异常对象上调用该函数。扩展方法本质上是扩展内置类/类型行为的方法,否则您将无法修改。

于 2012-05-24T03:04:55.497 回答
2

扩展方法如前所述,一些链接:

加上通常来自 Google 的数十篇博客文章和其他文档。

于 2012-05-24T03:06:28.617 回答
-1

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

于 2012-05-24T03:02:26.073 回答