如果我选择不同的通用限制,为什么我不能重载具有相同参数的方法?

发布于 2024-10-23 15:11:29 字数 598 浏览 2 评论 0原文

如果我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

纸伞微斜 2024-10-30 15:11:29

C# 中的重载解析根本不考虑约束。

来自 C# 规范:

7.5.3 重载解析

重载解析是一种绑定时机制
用于选择最佳功能成员
调用给定参数列表和一组候选函数成员

@Anthony Pegram 的博客链接是关于该主题的更好的阅读:
约束不是签名的一部分

Overload resolution in C# doesn't take constraints into account at all.

From the C# specification:

7.5.3 Overload resolution

Overload resolution is a binding-time mechanism
for selecting the best function member
to invoke given an argument list and a set of candidate function members.

The blog link by @Anthony Pegram is a much better read on the topic:
Constraints are not part of the signature

浮华 2024-10-30 15:11:29

重载仅基于函数参数。返回类型和模板参数(更具体地说:约束)不适用于重载函数。我无法告诉你为什么会这样(因为我没有编写该语言,并且不假装理解他们所有的担忧)。我只能告诉你编译器将允许什么。

您可能想要重载约束的原因之一可能是尝试完成 C++ 模板专业化的等效功能。不幸的是,C# 不支持这一点。 .Net 泛型和 C++ 模板是极其不同的野兽。

关于你的具体例子;有两种方法可以解决这个问题。两者都要求你以不同的方式思考你的问题。

真正的问题是你想要的用法会损害你的设计。重载实际上只是语法糖。重载可以帮助人们调用您的公共接口。它实际上对你内部没有帮助。事实上,如果重载方法执行明显不同的操作,那么在调试代码以及​​必须返回并维护代码时,推理代码就会变得更加困难。

由于调用这些函数的代码必须指定 T,因此您不会通过重载函数来节省任何维护成本。相反,您可以考虑将依赖项(集合)注入到这些方法中。

private static void myMethod(int obj, IDictionary dictionary)
{
    // do something with the dictionary here, setting private members while you do it
}

private static void myMethod(int obj, ICollection collection)
{
    // do something with the collection here, setting private members while you do it
}

如果此解决方案要求您过于频繁地重复 new Dictionarynew List 调用,或者如果您希望该方法控制实例的创建时间,您可以简单地给出超载。

private static void myMethodWithDictionary<T>(int obj) where T : IDictionary, new()
{
    // Create your new dictionary here, populate it, and set internal members
}

private static void myMethodWithCollection<T>(int obj) where T : ICollection, new()
{
    // Create your new collection here, populate it, and set internal members
}

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.

private static void myMethod(int obj, IDictionary dictionary)
{
    // do something with the dictionary here, setting private members while you do it
}

private static void myMethod(int obj, ICollection collection)
{
    // do something with the collection here, setting private members while you do it
}

If this solution would require you to duplicate your new Dictionary or new List calls too often, or if you want the method to control when the instance gets created, you can simply give up overloading.

private static void myMethodWithDictionary<T>(int obj) where T : IDictionary, new()
{
    // Create your new dictionary here, populate it, and set internal members
}

private static void myMethodWithCollection<T>(int obj) where T : ICollection, new()
{
    // Create your new collection here, populate it, and set internal members
}
早乙女 2024-10-30 15:11:29

如果您有一个这样的类 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文