简体   繁体   English

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

[英]The call is ambiguous between the following methods or properties (one static and one non-static)

Why am I not allowed to have a static and non-static methods with the same signature? 为什么我不允许使用具有相同签名的静态和非静态方法?

Let's say I have a class like this 假设我有一个这样的课程

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;
    }


}

and I try to use it like this 我试着像这样使用它

public class SomeOtherClass
{
    public SomeOtherClass()
    {
        TestClass tc = TestClass.ConvertTestClass(new object());

        TestClass tc2 = new TestClass();
        tc2.ConvertTestClass(new object());
    }
}

I get the following errors on TestClass.ConvertTestClass(new object()); 我在TestClass.ConvertTestClass(new object());上得到以下错误TestClass.ConvertTestClass(new object());

The call is ambiguous between the following methods or properties: 'TestClass.ConvertTestClass(object)' and 'TestClass.ConvertTestClass(object)' 以下方法或属性之间的调用是不明确的:'​​TestClass.ConvertTestClass(object)'和'TestClass.ConvertTestClass(object)'

and these errors on tc2.ConvertTestClass(new object()); tc2.ConvertTestClass(new object());上的这些错误tc2.ConvertTestClass(new object());

The call is ambiguous between the following methods or properties: 'TestClass.ConvertTestClass(object)' and 'TestClass.ConvertTestClass(object)' 以下方法或属性之间的调用是不明确的:'​​TestClass.ConvertTestClass(object)'和'TestClass.ConvertTestClass(object)'

Member 'TestClass.ConvertTestClass(object)' cannot be accessed with an instance reference; 无法使用实例引用访问成员'TestClass.ConvertTestClass(object)'; qualify it with a type name instead 用类型名称来限定它

Can the compiler really not tell the difference between the static and non static versions of that method or am I missing something here? 编译器真的不能告诉该方法的静态和非静态版本之间的区别,或者我在这里遗漏了什么?

I am not using ReSharper (which seemed to be the root of a similar problem in other questions). 我没有使用ReSharper(这似乎是其他问题中类似问题的根源)。

Its giving you an error, so its a safe bet that the compiler can't, or won't, discern between the two methods. 它给你一个错误,所以可以肯定的是编译器不能或不会在两种方法之间辨别。

Its probably a bad idea to do this kind of overload anyways, as it's unclear which method you are intending to invoke, but if that isn't enough, the C# 5 specification defines a method signature like this (Section 3.6): 无论如何都要做这种重载可能是一个坏主意,因为不清楚你打算调用哪种方法,但如果这还不够,C#5规范定义了这样的方法签名(第3.6节):

The signature of a method consists of the name of the method, the number of type parameters and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. 方法的签名包括方法的名称,类型参数的数量以及每个形式参数的类型和种类(值,引用或输出),按从左到右的顺序考虑。 For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. 出于这些目的,在形式参数类型中出现的方法的任何类型参数不是通过其名称来标识,而是通过其在方法的类型参数列表中的序号位置来标识。 The signature of a method specifically does not include the return type, the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints. 方法的签名特别不包括返回类型,可以为最右边的参数指定的params修饰符,也不包括可选的类型参数约束。

It doesn't explicitly mention static , but it also doesn't include it as part of the definition of a "signature". 它没有明确提到static ,但它也不包括它作为“签名”定义的一部分。 Thus, its fair to assume that by the spec, a method overload cannot differ only in the fact that it is static or instanced. 因此,假设通过规范,方法重载只能在静态或实例化的事实上有所不同。

I'd write this as a comment however it's easier to make this point in a proper editor. 我把它写成评论但是在适当的编辑器中更容易理解这一点。

I think you're only thinking about the logic of calling methods on the class externally ie from another class. 我认为你只是考虑从外部调用类的方法的逻辑,即从另一个类调用。 Within the class methods with the same signature only differing by static doesn't make any sense. 在具有相同签名的类方法中,仅静态不同没有任何意义。 eg you have a class with two methods as follows 例如,你有一个有两种方法的课,如下所示

public class MyClass
{
    public static void HellowWorld()
    {
        Console.WriteLine("Hello World!");
    }

    public void HellowWorld()
    {
        Console.WriteLine("Howdy World!");
    }

    public void Greet()
    {
        HellowWorld();
    }
} 

When compiling you'll see as long as one of the methods is commented out it compiles without errors. 编译时,只要其中一个方法被注释掉,它就会看到它编译时没有错误。 You should be able to alternate the commented out method and compile the class succesfully. 您应该能够替换注释掉的方法并成功编译该类。 Indicating there's no way of differentiating which method should be called within the scope of the class. 表明无法区分在类的范围内应该调用哪种方法。

You could argue that within the class you should be forced to use the same syntax to call a static method as you do externally eg 您可能会争辩说,在类中,您应该被迫使用相同的语法来调用静态方法,就像在外部调用一样

MyClass.HelloWorld();

However, this would defy scoping logic used throughout C#, why should you need to specify the class name within a class? 但是,这会违反整个C#中使用的范围逻辑,为什么需要在类中指定类名? I think such a change would also create ambiguity where the was none, and to do so now would of course break a lot of code out there. 我认为这样的改变也会造成模棱两可的现象,而现在这样做当然会破坏很多代码。

I think the compiler logic as it is makes perfect sense. 我认为编译器逻辑非常有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM