【发布时间】:2018-01-24 17:11:22
【问题描述】:
--- 更新:---
TL;DR
虽然不可能有两个方法(在相同的上下文中;例如在同一个类中)只有返回类型不同,有可能以不同的方式解决问题:
“返回”out 参数中的值。
(C#) 不好:
// WON'T COMPILE
int myfunc() { ... }
double myfunc() { ... }
(C#) 好:
void myfunc(out int value) { ... }
void myfunc(out double value) { ... }
--- 原始问题 ---
是的,这与“方法的通用接口重载”非常相似。感谢您找到该线程。但是请注意,它不是“完全重复的”。
请阅读一旦 Q 被标记为重复时插入的文本栏 - 它表明“重复问题”的目的是标记问题何时是精确的现有问题的重复,因此不会对 SO 添加任何内容。正如我在下面解释的那样,针对三个提议的重复,这是不正确的(IMO)。添加答案或评论链接到相关问答并解释连接会更有帮助,而不是标记为重复。
在那种情况下,OP 正在使用泛型,如果不深入研究细节就不清楚,错误是试图仅通过返回类型来区分。在这里,OP 专注于 OVERLOADING,并认为答案可能是泛型(不是)。
认为这是关于方法签名的问答的副本是错误的。有人(包括我之前)没有理解“重载+仅通过返回的值不同”的解决方案是通过使用“out”参数来解决的,可能只是通过阅读感到困惑那个问答。
考虑一个尚未理解某个主题的人的心态。 相关问答之间存在差异,它的答案可能对某人有用该问答的链接,以及一个重复问答,这是一个非常相似的线程。
我不认为这是 How to use generic method with "out" variable 的重复。
之所以不同,是因为目标不同。
是的,解决方案是一个输出参数,但目标是找到一种方法来重载方法仅通过返回的值不同。
多年来,我一直认为这样做是不可能,因为“返回值不是方法签名的一部分。”
但是,我认为通过所有语言增强功能,现在这可能是可能的。 (直到今天我才意识到,有可能以不同的方式思考这个问题。我想我不是唯一一个对此感到迟钝的人。因此有这个问答。)
其他问题只有在知道解决方案是一个输出参数的人时才对他们有所帮助。 (该问题未提及“扩展”或“返回”/“返回值”。)
我有很多类似这样的 VB 读/写代码:
Public Structure MyVertex
Public Position As Vector3
Public Normal As Vector3
Public TextureCoordinates As Vector2
Public Sub Read(br As BinaryReader)
Position = br.ReadVector3()
Normal = br.ReadVector3()
TextureCoordinates = br.ReadVector2()
End Sub
Public Sub Write(bw As BinaryWriter)
bw.WriteVector3(Position)
bw.WriteVector3(Normal)
bw.WriteVector2(TextureCoordinates)
End Sub
End Structure
其中读/写方法是扩展方法,例如
Public Module ReadWriteExtensions
<Extension()>
Public Function ReadVector2(br As BinaryReader) As Vector2
Dim v2 As New Vector2()
v2.X = br.ReadSingle()
v2.Y = br.ReadSingle()
Return v2
End Function
<Extension()>
Public Function ReadVector3(br As BinaryReader) As Vector3
...
End Function
<Extension()>
Public Sub WriteVector2(bw As BinaryWriter, v2 As Vector2)
...
<Extension()>
Public Sub WriteVector3(bw As BinaryWriter, v3 As Vector3)
...
End Module
我知道我可以使用参数类型的“重载”来简化 Write 方法以使其具有相同的名称。 (我使用“WriteT”来区分内置的 BinaryWriter 方法,但我可以简单地使用“Write”。):
Public Sub WriteT(bw As BinaryWriter, v2 As Vector2)
...
Public Sub WriteT(bw As BinaryWriter, v3 As Vector3)
...
因此使用变得更容易:
Public Sub Write(bw As BinaryWriter)
bw.WriteT(Position)
bw.WriteT(Normal)
bw.WriteT(TextureCoordinates)
End Sub
但我没有这样做,因为我看不到如何执行与“读取”方法等效的操作。显而易见的尝试失败了,因为方法仅在返回类型上有所不同:
<Extension()>
Public Function ReadT(br As BinaryReader) As Vector2
...
<Extension()>
Public Function ReadT(br As BinaryReader) As Vector3
...
导致编译器错误“已声明具有相同名称或签名的成员...”。
有什么方法可以达到预期的效果吗?
(C# 的答案也很有用。)
【问题讨论】:
-
@djv - 这不是那个问题的重复,因为这里的目标完全不同:很多年我有希望我可以像编写“Write”方法一样编写类似的“Read”方法。但是我当然不能[只要我认为“返回”作为方法的返回值],因为返回值不是签名的一部分。是的,解决方案是使用“输出参数”,但这不是问题。问题是“如何重载仅因返回值不同的方法?” overload 是该问题的关键词。
-
@djv ...而且我并不是唯一一个一开始忽略这一点的人。有趣的是,核心 .NET 读取类的内置方法(例如 BinaryReader)使用了与我最初展示的相同的繁琐命名。这就是我多年前复制的风格。有趣的是他们不使用 out 参数来解决这个问题。尽管他们确实对“写”方法使用了重载!
-
所以你提出了一个问题,并在一分钟内回答“否”并提供了一个替代解决方案,顺便说一句,这与this answer 几乎相同。如果我可以标记重复的答案,我会的。
-
欺骗不是关于 question 是否与其他问题重复,而是关于是否存在可行的现有 answer。这就是为什么欺骗文本的措辞如下:这个问题在这里已经有了答案:如果后来/欺骗仍然存在,它就充当了一个“路标”,以汇集其他未来的变体答案(假设他们进行搜索)
-
我发表评论只是为了澄清关于受骗的事情,而不是就帖子的细节展开新的争论(我没有研究它)。但是,这并不完全是 SO 的工作方式。一个问题 can 被快速删除,它已关闭 - 在那之前我们不能 VTD。答案只需要有一个 DV,然后那些可以 VTD 的人就可以这样做。否则,即使是接受了答案的 DV 问题也可能永远存在(IIRC - 很多与此相关的愚蠢规则)。而且,答案是关于代码而不是概念。我会冒险 大多数 问题在发布时不知道他们到底在寻找什么(XY 问题)