如果我选择不同的通用限制,为什么我不能重载具有相同参数的方法?
如果我在 c# 4.0 .NET 中执行此操作,
private static void myMethod<T>(int obj) where T : IDictionary
{
}
private static void myMethod<T>(int obj) where T : ICollection
{
}
则会收到以下错误。
类型 'ConsoleApplication1.Program' 已经 定义一个名为“myMethod”的成员 具有相同的参数 类型
我想知道为什么?据我所知,这两种方法都可以毫无歧义地调用?
如果我想要第一种方法,我会这样做
myMethod<IDictionary>(50)
,第二种方法
myMethod<ICollection>(40)
我错过了什么场景?有没有办法实现一组参数相同但类型不同的重载方法?
If I do this in c# 4.0 .NET
private static void myMethod<T>(int obj) where T : IDictionary
{
}
private static void myMethod<T>(int obj) where T : ICollection
{
}
I get the following error.
Type
'ConsoleApplication1.Program' already
defines a member called 'myMethod'
with the same parameter
types
I would like to know why? As far as I see, both these methods can be called without ambiguity?
If I wanted the first method, I'd do this
myMethod<IDictionary>(50)
and second method
myMethod<ICollection>(40)
What scenario am I missing? And is there a way to achieve a set of overloaded methods with the same parameters but a different type?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C# 中的重载解析根本不考虑约束。
来自 C# 规范:
@Anthony Pegram 的博客链接是关于该主题的更好的阅读:
约束不是签名的一部分
Overload resolution in C# doesn't take constraints into account at all.
From the C# specification:
The blog link by @Anthony Pegram is a much better read on the topic:
Constraints are not part of the signature
重载仅基于函数参数。返回类型和模板参数(更具体地说:约束)不适用于重载函数。我无法告诉你为什么会这样(因为我没有编写该语言,并且不假装理解他们所有的担忧)。我只能告诉你编译器将允许什么。
您可能想要重载约束的原因之一可能是尝试完成 C++ 模板专业化的等效功能。不幸的是,C# 不支持这一点。 .Net 泛型和 C++ 模板是极其不同的野兽。
关于你的具体例子;有两种方法可以解决这个问题。两者都要求你以不同的方式思考你的问题。
真正的问题是你想要的用法会损害你的设计。重载实际上只是语法糖。重载可以帮助人们调用您的公共接口。它实际上对你内部没有帮助。事实上,如果重载方法执行明显不同的操作,那么在调试代码以及必须返回并维护代码时,推理代码就会变得更加困难。
由于调用这些函数的代码必须指定 T,因此您不会通过重载函数来节省任何维护成本。相反,您可以考虑将依赖项(集合)注入到这些方法中。
如果此解决方案要求您过于频繁地重复
new Dictionary
或new List
调用,或者如果您希望该方法控制实例的创建时间,您可以简单地给出超载。Overloads are only based on function parameters. Return types and template parameters (more specifically: constraints) do not work for overloading a function. I can't tell you why this is (since I didn't write the language, and don't pretend to understand all their concerns). I can only tell you what the compiler will allow.
One reason that you might want to overload on constraints might be to try to accomplish the equivalent of C++ template specialization. Unfortunately, C# doesn't support this. .Net generics and C++ templates are extremely different beasts.
Regarding your specific example; there are two ways to solve this. Both require you to think about your problem differently.
The real problem is that the usage you are intending hurts your design. Overloading is really just syntactic sugar. Overloading helps people call your public interface. It doesn't actually help you internally. In fact, if the overloaded methods do significantly different things, it can make it much harder to reason about your code while you are debugging it, and when you have to come back and maintain it.
Since the code that calls these functions has to specify T, you aren't saving any maintenance costs by overloading the function. Instead, you could consider injecting the dependency (the collection) into these methods.
If this solution would require you to duplicate your
new Dictionary
ornew List
calls too often, or if you want the method to control when the instance gets created, you can simply give up overloading.如果您有一个这样的类
public classWhatever : IDictionary, ICollection
会发生什么?编译器不知道要使用哪个重载。What happens if you have a class such that
public class Whatever : IDictionary, ICollection
? The compiler wouldn't know which overload to use.