C# 以下方法或属性之间的调用不明确(一个是静态的,一个是非静态的)

C# 以下方法或属性之间的调用不明确(一个是静态的,一个是非静态的),c#,C#,为什么不允许我拥有具有相同签名的静态和非静态方法 比如说我有一门课是这样的 public class TestClass { public object thing { get; set; } public TestClass() { } public TestClass(object thing) { this.thing = thing; } public static TestClass Convert

为什么不允许我拥有具有相同签名的静态和非静态方法

比如说我有一门课是这样的

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());
    }
}
我试着这样使用它

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(newobject())上遇到以下错误:

以下方法或属性之间的调用不明确:“TestClass.ConvertTestClass(对象)”和“TestClass.ConvertTestClass(对象)”

以及
tc2.ConvertTestClass(newobject())上的这些错误

以下方法或属性之间的调用不明确:“TestClass.ConvertTestClass(对象)”和“TestClass.ConvertTestClass(对象)”

无法使用实例引用访问成员“TestClass.ConvertTestClass(object)”;改为使用类型名称限定它

编译器真的不能区分该方法的静态版本和非静态版本吗?或者我在这里遗漏了什么


我没有使用ReSharper(这似乎是其他问题中类似问题的根源)。

它会给您一个错误,因此编译器肯定无法或不会区分这两种方法

无论如何,执行这种重载可能不是一个好主意,因为不清楚您打算调用哪种方法,但如果这还不够,C#5规范定义了一个这样的方法签名(第3.6节):

方法的签名由方法的名称、 类型参数的数量以及类型和种类(值、引用或 输出)的每个形式参数,按左顺序考虑 向右。出于这些目的,方法的任何类型参数 发生在形式参数的类型中,而不是由其 名称,但按其在 方法。方法的签名特别不包括 返回类型,可以为 最右边的参数,也不是可选的类型参数约束


它没有明确提到
静态
,但也没有将其作为“签名”定义的一部分。因此,可以公平地假设,根据规范,方法重载不能仅在它是静态的或实例的这一事实上有所不同。

我将此作为注释来写,但是在适当的编辑器中更容易说明这一点

我认为您只考虑从外部(即从另一个类)调用类上的方法的逻辑。在具有相同签名的类方法中,仅在静态上有所不同没有任何意义。e、 g您有一个包含两个方法的类,如下所示

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#中使用的作用域逻辑,为什么需要在类中指定类名?我认为这样的改变也会在没有的地方产生歧义,现在这样做当然会破坏很多代码


我认为编译器的逻辑是非常合理的。

您希望通过
ConvertTestClass(new object())
从内部
TestClass
?;)调用什么但最终,这可能是为了清晰起见而做出的设计决定。@Marvin,这肯定是模棱两可的。但是,说
this.ConvertTestClass
TestClass.ConvertTestClass
不会解决歧义吗?有时我们会被要求为编译器做类似的澄清(
System.Windows.Shapes.Path
/
System.IO.Path
)看看Jon写的Skeet@chomba该死,我的Google foo让我失望了。谢谢你的链接。我说这不是重复的唯一原因是Jon Skeet的优秀答案指的是类内调用,而不是像这里提供的示例那样的外部调用。对此有点犹豫。如果你想让我把它作为一个副本关闭,我会的。第7.6.4节和第10.6.2节似乎建议编译器可以区分不同的。我的意思是这通常是允许的
this.thing=thing
@Brad现在正在阅读这些,但我从来没有说过编译器不理解
静态
是如何工作的,只是它不是用于重载的签名的一部分。是的,我听到了。这可能只是“事情就是这样”之类的东西。@Brad看完后,它仍然没有提到过载。充其量10.6.2表明这不重要,因为静态方法只能通过类型名调用,而实例只能通过实例调用。因此,这实际上不是一个模棱两可的调用,尽管重载规则表明并非如此。