为什么即使返回类型不同,也不能使用相同的签名声明两个方法?

时间:2009-02-25 03:57:58

标签: c# method-signature

重复Function overloading by return type?


也许这是一个非常愚蠢的问题,但我不明白为什么当它们有不同的返回类型时我不能声明两个具有相同签名的方法。

public class MyClass
{
    private double d = 0;

    public double MyMethod()
    {
        return d;
    }

    public string MyMethod()
    {
        return d.ToString();
    }
}

我收到一个编译错误,指出该类已经定义了一个具有相同参数类型的成员。

(显然我在我的代码中使用它的方式并不像我的示例代码那么简单......但我认为它可以解决这个问题。)

我是否遗漏了有关OO设计的内容,这使得我正在尝试使用OOP反模式?当然,编译器应该能够确定我尝试使用哪种方法,只要我明确告诉它我想要哪一种方法。

鉴于MyClass myClass = new MyClass();,我希望以下代码能够正常运行:

double d = myClass.MyMethod();
string s = myClass.MyMethod();

我希望以下代码有问题:

var v = myClass.MyMethod();

但即使在var的情况下,它也会导致编译错误。

谁能看到我在这里做错了什么?我很高兴得到纠正。 : - )

5 个答案:

答案 0 :(得分:17)

这是因为类型强制。

假设您有以下功能:

int x(double);
float x(double);

double y = x(1.0);

现在,你应该打电话给两个原型中的哪一个,特别是如果他们做了两件完全不同的事情?

基本上,在语言设计的早期做出决定只使用函数名和参数来决定调用哪个实际函数,并且在新标准到来之前我们一直坚持这样做。

现在,您已经标记了您的问题C#,但我认为设计一种可以做您所建议的语言并没有错。一种可能性是将上述任何模糊命令标记为错误,并强制用户指定应该调用哪些命令,例如使用强制转换:

int x(double);
float x(double);
double y = (float)(x(1.0));    // overload casting
double y = float:x(1.0);       // or use new syntax (looks nicer, IMNSHO)

这可以允许编译器选择正确的版本。这甚至适用于其他答案提出的一些问题。你可能会变得含糊不清:

System.out.Println(myClass.MyMethod());

具体到:

System.out.Println(string:myClass.MyMethod());

这可能会被添加到C#,如果它在标准流程中不太远(微软会倾听)但我认为你没有把它添加到C的机会。或C++没有太大的努力。也许将其作为gcc的扩展名会更容易。

答案 1 :(得分:6)

在没有“捕获”返回类型的情况下,阻止您调用方法没有任何结果。没有什么可以阻止你这样做:

myClass.MyMethod();

在这种情况下,编译器如何知道要调用哪一个?

编辑:除此之外,在C#3.0中,当您可以使用 var 时,编译器将如何知道您执行此操作时调用的方法:

var result = myClass.MyMethod();

答案 2 :(得分:1)

因为在调用方法时返回类型并不重要。在许多情况下,如果方法仅因返回类型而不同,则会导致模糊。您可能根本不会将结果存储在变量中,或者执行以下操作:

System.out.Println(myClass.MyMethod());

编译器无法弄清楚您要调用哪种方法。

答案 3 :(得分:0)

方法签名只是名称和输入参数(类型和顺序)。返回类型不是签名的一部分。因此,具有相同名称和输入参数的两个方法是相同的并且彼此冲突。

答案 4 :(得分:0)

您分配方法的变量(如果有),无法通知编译器使用哪种方法。想象:

String message =“Result =”+ myClass.MyMethod();