为什么我不允许使用具有相同签名的静态和非静态方法?
我们说我有这样的课程
public class TestClass
{
public object thing { get; set; }
public TestClass()
{
}
public TestClass(object thing)
{
this.thing = thing;
}
public static TestClass ConvertTestClass(object thing)
{
return new TestClass(thing);
}
public TestClass ConvertTestClass(object thing)
{
this.thing = thing;
return this;
}
}
我试着像这样使用它
public class SomeOtherClass
{
public SomeOtherClass()
{
TestClass tc = TestClass.ConvertTestClass(new object());
TestClass tc2 = new TestClass();
tc2.ConvertTestClass(new object());
}
}
我在TestClass.ConvertTestClass(new object());
以下方法或属性之间的调用不明确:' TestClass.ConvertTestClass(object)'和' TestClass.ConvertTestClass(对象)'
以及tc2.ConvertTestClass(new object());
以下方法或属性之间的调用不明确:' TestClass.ConvertTestClass(object)'和' TestClass.ConvertTestClass(对象)'
会员' TestClass.ConvertTestClass(对象)'无法使用实例引用访问;使用类型名称来限定它
编译器真的不能区分该方法的静态和非静态版本,或者我在这里遗漏了什么?
我没有使用ReSharper(在其他问题中似乎是类似问题的根源)。
答案 0 :(得分:4)
它给你一个错误,因此可以安全地认为编译器不能或不会在两种方法之间辨别。
无论如何都要做这种过载可能是一个坏主意,因为它不清楚你打算调用哪种方法,但如果这还不够,C#5规范定义了一个方法签名,如这(第3.6节):
方法的签名由方法的名称组成 类型参数的数量以及类型和种类(值,参考或 输出)每个形式参数,按左侧顺序考虑 对。出于这些目的,该方法的任何类型参数 在形式参数的类型中发生的不是由它识别的 name,但是通过它在类型参数列表中的序号位置 方法。方法的签名特别不包括 返回类型,可以为其指定的params修饰符 最右边的参数,也没有可选的类型参数约束。
它没有明确提及static
,但它也没有将其作为"签名"的定义的一部分。因此,可以假设,通过规范,方法重载只能在静态或实例化的事实上有所不同。
答案 1 :(得分:0)
我将此作为评论写下来,但在适当的编辑器中更容易理解这一点。
我认为你只是考虑从外部调用类的方法的逻辑,即从另一个类调用。在具有相同签名的类方法中,只有静态不同才有意义。例如,你有一个有两种方法的类,如下所示
public class MyClass
{
public static void HellowWorld()
{
Console.WriteLine("Hello World!");
}
public void HellowWorld()
{
Console.WriteLine("Howdy World!");
}
public void Greet()
{
HellowWorld();
}
}
在编译时,只要其中一个方法被注释掉,它就会看到它编译没有错误。您应该能够替换注释掉的方法并成功编译该类。表明在类的范围内无法区分应该调用哪种方法。
你可能会争辩说,在课堂上,你应该被迫使用相同的语法来调用静态方法,例如。
MyClass.HelloWorld();
但是,这会违反整个C#中使用的作用域逻辑,为什么需要在类中指定类名?我认为这样的改变也会造成模棱两可的现象,而现在这样做当然会破坏很多代码。
我认为编译器逻辑非常有意义。