具有不同返回类型的方法重载[重复]

Posted

技术标签:

【中文标题】具有不同返回类型的方法重载[重复]【英文标题】:Method Overloading with different return type [duplicate] 【发布时间】:2014-01-09 10:26:27 【问题描述】:

我想深入了解它是否提供了歧义或额外功能:

 public class Foo 
  
    public int Bar()
       //code
    

    public string Bar(int a)
       //code
    
 

任何对此有任何经验的人,使用不同参数重载返回类型应该是一种不好的做法,是吗?

但是,如果重载是基于返回类型完成的,那么为什么这不起作用。

 public class Foo 
  
    public int Bar(int a)
       //code
    

    public string Bar(int a)
       //code
    
 

如果我们调用 obj.Bar(); 将无法决定调用第一个或第二个函数; ,它应该以错误结束有没有人知道为什么它允许第一个代码 sn-p 运行。

【问题讨论】:

你能把你的问题说清楚一点吗?我想大家都误解了你的问题。 @ChrisLava 除了答案中给出的含义之外,还有什么其他可能的含义? @Rotem 他说他知道为什么第二个代码 sn-p 失败(“无法决定调用哪个函数”)。所以他明白这一点。但在我看来,他在问“使用不同参数重载返回类型”(第一个代码 sn-p)是否是不好的做法。 @ChrisLava 这就是我所认为的 - 并相应地回答了 @Rotem 没关系。不是你的错。这个问题可能会更清楚。事实上,整个第二个代码 sn-p 应该消失,他应该只问第一个代码 sn-p 是不是不好的做法。 【参考方案1】:

C# 规范(第 10.6 节)指出,重载的成员可能仅因返回类型和http://msdn.microsoft.com/en-us/library/ms229029.aspx 而不同

根据您关于创建参数只是为了支持不同的返回类型的问题?我个人认为这是解决问题的糟糕方法。代码维护将变得困难,未使用的参数是明确的代码气味。在这种情况下,该方法真的需要重载吗?或者它属于那个类?是否应该创建其他东西来从一种返回类型转换为另一种?为了得出更惯用的解决方案,您应该提出所有要求。

【讨论】:

【参考方案2】:

这在逻辑上是不可能的。考虑以下调用:

object o = Bar(42);

甚至

var o = Bar(42);

编译器如何知道调用哪个方法?

编辑: 既然我理解了您的实际要求,我认为通过无意义的参数进行重载是不好的做法,并且会降低可读性,最好通过方法名称来区分:

 string BarToStr()
 

 

 int BarToInt()
 

 

【讨论】:

编译器可能会产生错误,如果它无法解决正确的重载。这将允许string foo = BarToStr()。有关更多信息,请参阅已关闭的重复答案。 在当前语言中可能是不可能的。这当然不是“逻辑上不可能的”。正如 Eric J. 所说,如果线路类似于 String foo = Bar(),那么选择一种方法会很容易。在像Object foo = Bar() 这样的情况下,在我看来,让程序员消除与Object foo = Bar<String>() 这样的歧义是很容易的。已经存在通过类型参数重载的类似功能。我不认为这是不可能或不可行的任何实际原因,它只是尚未实施,也许是出于历史原因。 也说明了“var”的局限性。【参考方案3】:

其他人已经解释了情况。我只想补充一点:您可以通过使用泛型类型参数来做您想做的事情:

public T Bar<T>(int a) 
   // code

然后这样称呼它:

int i = Bar<int>(42);
string s = Bar<string>(42);

问题是通常很难用泛型类型做一些有意义的事情,例如您不能对其应用算术运算。有时generic type constraints 可以提供帮助。

【讨论】:

// 代码部分会是什么样子?你能在 上做一个 switch 语句吗? 见:***.com/a/9802588/880990 我认为这不适用于非本地类型。 对于其他类型,您必须使用 if-else。但是更好的方法(如果可能的话)是定义一个接口并将其应用为泛型类型约束where T : IMyInterface【参考方案4】:

你不能通过仅仅改变它们的返回类型来重载函数。 只能通过以下方式重载函数

    参数类型 参数个数 方法中声明的参数顺序

你无法知道实际调用了哪个函数(如果可能的话)。

我想补充的还有一件事是 函数重载是提供一个同名但签名不同的函数。但方法的返回类型不被视为方法签名的一部分。

所以这是理解为什么方法重载不能仅通过返回类型来完成的另一种方式。

【讨论】:

这部分是不真实的。返回类型签名的一部分。事实上,CLR 允许按返回类型进行重载,就像 F# 等其他语言一样。只是C#没有。另一种看待它的方式是,如果没有返回类型,就无法唯一地描述方法或函数所遵循的协定。【参考方案5】:

任何对此有任何经验的人,在返回类型上重载 使用不同的参数应该是一种不好的做法,是吗?

我的意思是-“使用不同的参数组合来促进不同的返回类型是不好的做法”-如果确实是这个问题,那么想象一下其他人在几个月后遇到此代码-有效地“虚拟”参数来确定返回类型......很难理解发生了什么。

编辑 - 正如 ChrisLava 指出的那样“解决这个问题的方法是为每个函数设置更好的名称(而不是重载)。在应用程序中具有明确含义的名称。没有理由 Bar 应该返回一个 int 和一个字符串. 我可以看到只是在 int 上调用 ToString()"

【讨论】:

没错!这是我理解的问题。其他人都误会了。但这不是他们的错,因为 OP 对这个问题的措辞很糟糕。 很高兴不只是我这样读! 为了补充您的答案,我认为这是不好的做法,解决此问题的方法是为每个函数设置更好的名称(而不是重载)。在应用程序中具有明确含义的名称。 Bar 没有理由返回一个 int 和一个字符串。我可以看到只是在 int 上调用 ToString()。 同意 - 已与您的 cmets 更新答案 @ChrisLava 我明白你的意思,但我目前处于结构级别,实际功能会做一些复杂的事情。【参考方案6】:

C# does not allow it.

另一方面,C# 不支持基于 返回类型;这是语言设计者有意识的决定 不要暴露允许它的 CLR 的功能。没有 他们无法做到的技术原因,他们只是感觉更好 不要。因为返回值不用于方法选择 C# 方法签名不包含它。

【讨论】:

【参考方案7】:

检查这个.. 你不能有具有相同签名和不同返回类型的方法。在这个问题中提到了推荐。

C# Overload return type - recommended approach

【讨论】:

【参考方案8】:

您的代码将导致编译器错误。您不能拥有具有相同参数和不同返回类型的同名方法,调用者将不知道要调用哪个方法(将无法解析要调用的方法在内存中的位置,为什么编译器会不允许)。您的替代方法是返回一个对象并根据调用者知道的内容进行转换。即便如此,这似乎也是糟糕的设计。

这会工作(意味着编译),但仍然是糟糕的设计。

public class Foo

    public object Bar(int a)
    
        return a;
    

【讨论】:

【参考方案9】:

您不能创建具有相同名称、相同数量和类型的参数的方法。

更多详情请参考link。

【讨论】:

以上是关于具有不同返回类型的方法重载[重复]的主要内容,如果未能解决你的问题,请参考以下文章

java中重载,继承,重写和多态的区别

什么是java方法重载

方法的重载与重写

Java重载和重写的区别

重载与重写

问题1 重载和重写的区别