【发布时间】:2012-02-08 02:50:50
【问题描述】:
遇到了更高级的扩展和静态方法的冲突问题,我举例并简化了一些代码:
using System;
namespace Test
{
static class EM
{
public static string To(this object o)
{
return o.GetType().ToString();
}
}
class A
{
public static string To() { return "Test.A"; }
}
class B { }
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
object o = null;
o.To();
B b = null;
b.To();
A a = null;
a.To();
A.To();
}
}
}
当 .NET 编译器(从 3.x 到 4.y)未能解决应该在“a.To();”出现的行中调用哪个方法时,我感到很惊讶。当然,我解释了编译器,但这就是可以带来错误消息的内容(字面意思是“Member 'Test.A.To()' cannot be accessed with an instance reference; qualify it with a type name instead”)。
我发布这篇文章是因为没有详细说明编译器为何会提醒程序员(已经知道规则),而是更多地促进讨论,以接近或最终解决此类问题(考虑帐户继承)在 Microsoft 之前,人类可以轻松判断扩展/静态方法调用匹配,而编译器甚至不提供确切的程序员错误描述或提示。
期待听到“stackoverflowers”的消息。
【问题讨论】:
-
你说它在
a.To()上失败了,但是你引用的错误消息说A.To()。你的意思是什么? -
@Shymep - 你是对的 - 请忽略我之前的评论。
-
但这甚至与扩展方法无关是吧。如果您尝试使用对实例的引用来调用任何静态方法,您将收到相同的错误消息。扩展方法的存在不应突然改变类型本身的行为。
-
@BrianRasmussen 但是如果人们认为(错误但合理地)静态方法不是重载解决方案的“适用候选者”,则可以合理地期望选择扩展方法。在我看来,一个在给定上下文中不能合法调用的方法在重载决议的候选集中不会被考虑在我看来当然是合理的。甚至 Eric Lippert 也称这些规则“令人困惑”。
-
@phoog:我并不是说这并不令人困惑,我同意 Eric 比我解释得更好。
标签: c# inheritance methods static