为啥不能用相同的签名声明两个方法,即使它们的返回类型不同? [复制]

Posted

技术标签:

【中文标题】为啥不能用相同的签名声明两个方法,即使它们的返回类型不同? [复制]【英文标题】:Why can't two methods be declared with the same signature even though their return types are different? [duplicate]为什么不能用相同的签名声明两个方法,即使它们的返回类型不同? [复制] 【发布时间】:2010-10-09 17:43:14 【问题描述】:

重复: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,它也会导致编译错误。

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

【问题讨论】:

谢谢格雷格!我不知道这是一个重复的问题。我在询问之前进行了搜索......但我想我没有使用正确的术语。 不用担心,我链接到的问题有一些非常好的答案。 (我的只是平庸。:) 是的,我通读了他们,他们肯定回答了我的问题。我不介意这个问题是否被关闭......但如果它没有被删除会很好,这样如果下一个有这个问题的人不知道它导致的“返回类型的函数重载”他们可以仍然找到答案。 那是“被称为”而不是“导致”的......我希望在这种情况下我可以编辑我的 cmets...... @mezoid,我倾向于将旧评论剪切并粘贴到新评论中,并在提交前修复它。那么只要30秒内没有人评论原评论(即新评论乱序),我就删除旧评论,否则我删除新评论。 【参考方案1】:

这是因为类型强制。

假设你有以下功能:

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#,如果它不是太远进入标准流程(微软会听),但我认为你没有太多机会将它添加到CC++没有非常大的努力。也许将其作为gcc 的扩展会更容易。

【讨论】:

如你所说,这是一个语言设计问题。根据 Don Box 的说法,CLI 确实允许返回类型重载(尽管没有语言允许)。 amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117/…【参考方案2】:

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

myClass.MyMethod();

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

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

var result = myClass.MyMethod();

【讨论】:

【参考方案3】:

因为在调用方法时返回类型并不是那么重要。在许多情况下,只有返回类型不同的方法会导致歧义。您可能根本不会将结果存储在变量中,或者执行以下操作:

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

编译器无法确定您要调用哪些方法。

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

字符串消息 = "结果 = " + myClass.MyMethod();

【讨论】:

以上是关于为啥不能用相同的签名声明两个方法,即使它们的返回类型不同? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

C#委托初学

C# 方法签名以及怎样的两个方法才算是不同的方法

█■为啥要用实现接口的类实例化接口呢? ?

为啥我不能拥有带有此签名的 Q_PROPERTY?

为啥继承具有名称签名的接口成员的 C# 抽象类至少需要实现其中一个?

为啥我们要实现标记接口,即使它们不包含任何方法? [复制]