为什么“;这个“;此处需要(扩展方法)
本文关键字:扩展 方法 这个 为什么 | 更新日期: 2023-09-27 17:58:54
元注释:不可能搜索单词"this"
我刚刚在ASP.NET中遇到一个奇怪的场景,其中需要this
关键字。但这并不是为了解决局部变量和实例变量之间的问题,正如您在构造函数中看到的那样。
Microsoft.Web.Mvc包含一个名为ControllerExtensions
的类,我正在使用RedirectToAction(Expression<Action<TController>> action)
重载。也许这很特别,因为过载是一个扩展。
RedirectToAction(c => c.Index())
不会编译,它说Cannot convert lambda expression to type 'string' because it is not a delegate type
。在我看来,这听起来像是在使用第一个重载,它需要一个字符串。
this.RedirectToAction(c => c.Index())
编译良好。我也可以静态地调用它,传递this
作为第一个参数。
-
为什么编译器不能弄清楚我正在寻找接受表达式的重载,并使用它?因为该方法采用一个操作的表达式,而不仅仅是一个操作,所以必须涉及该操作。我根本不了解Expressions命名空间,所以我不知道使用此参数类型的目的。
-
不管#1的答案是什么,为什么简单地添加
this
就能解决所有问题?
扩展方法就是这样工作的。
根据C#规范(7.6.5.2 Extension method invocations
),只有当调用具有"其中一种形式"时,才使用扩展方法:
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )
这基本上意味着你必须在"."的左边有一些东西,才能让编译器解析一个扩展方法。expr.
部分必须存在(而不是dynamic
),编译器才能查找扩展方法。
例如,这里有一个小测试演示:
namespace TestNamespace
{
using System;
public static class TextExtension
{
public static void Print(this Test test)
{
Console.WriteLine("Found");
}
}
public class Test
{
public void Foo()
{
// Compiler error!
Print();
// Works fine
this.Print();
}
static void Main()
{
Test test = new Test();
test.Foo();
// Fine here
test.Print();
Console.ReadKey();
}
}
}
请注意编译器错误——由于我们在Test实例内部,如果不使用this.
,就不能直接调用Print()
。然而,我们可以很容易地进行test.Print()
(或测试中的this.Print()
)。
我可以回答#2:您的类(this
)只有一个RedirectToAction方法,所以没有歧义。我敢打赌,如果String
过载,你会再次出现错误。
存在歧义。
当您使用'this'时,您会调用此方法-
Controller.RedirectToAction
如果没有"this",则调用扩展方法-
Microsoft.Web.Mvc.ControllerExtensions.RedirectToAction