已经注意到here(并且非常正确),.NET中的扩展方法只是实例变量上静态方法调用的语法糖。
然而,就this question而言,我想知道为什么语言规范中省略了静态访问的扩展方法?
除了作为.NET(C#)开发人员之外,我也是一名JavaScript开发人员,你可以在JavaScript中模拟静态方法扩展的等价物 - 因此我的理由是更深入地研究这个论点。 (请不要因为比较.NET和JavaScript而投票给我。我很清楚.NET和JavaScript是两种截然不同的语言!)
让我们检查扩展方法的语法及其编译方式:
public static string Hash(this string value)
{
// some logic here...
}
string x = "Hello World";
x.Hash();
编译到
public static string Hash(string value)
{
// some logic here...
}
string x = "Hello World";
Hash(x);
如果您尝试为静态类型创建变量
class MyClass
{
Console c; // error!
}
你不能!
如果您尝试将静态类型作为方法参数传递
public void DoThis(Console c) // error!
{
}
你不能!
所以这定义了语言规范的限制,但是就扩展方法而言,我可以看到实现是这些方面的......
public static void WriteLineInGreen(static Console c, string formatString, params object[] args)
{
c.ForeGround = ConsoleColor.Green;
c.WriteLine(formatString, args);
}
Console.WriteLineInGreen("Hello World {0}, {1}, {2}", ":-)", 1234, true);
好的,这是不可能的...为什么我仍然问?答案......“Roslyn项目”。您认为这是我们可能会看到的所有其他语言规范更改,将在Project Roslyn中实现吗?
编辑对Roslyn语言扩展感兴趣的任何人都应该注意这一点:https://channel9.msdn.com/Events/Build/2014/2-577
答案 0 :(得分:1)
您无法创建静态类型的实例。 var c = new Console();
不起作用。因此,您不能使用静态类型的参数。在Console c
中,c
会是什么?您提出的静态类型扩展方法的语法必须是这样的:
public static void WriteLineInGreen(static Console, string formatString,
params object[] args)
{
Console.ForeGround = ConsoleColor.Green;
Console.WriteLine(formatString, args);
}
我认为与Roslyn相关的语言规范更改是由于在使用Roslyn时发现语言规范不一致和不准确。对我来说似乎不太合理,任何新的C#语言功能都与Roslyn有关。
更新:嗯,我最后一点错了。正如@svick在他的评论中指出的那样,新编译器的更好结构使得更容易实现语言更改。
另一个重要原因是语言和编译器开发已成为开源。 Microsoft邀请社区参与。 (见:C# 7 Work List of Features。)