C# - 我怎样才能“重载”代表?

发布于 2024-09-24 06:10:26 字数 514 浏览 7 评论 0原文

首先,我阅读了一些论坛和 MSDN 中的帮助,都说委托不能超载。

现在,我想要这样的东西:

public delegate void OneDelegate();
public delegate void OneDelegate(params object[] a);

public void DoNothing(params object[] a) {}
public void DoSomething() { /* do something */ }

private OneDelegate someFunction;

someFunction = new OneDelegate(DoSomething);
someFunction = new OneDelegate(DoNothing);

所以,正如你所知,你不能这样做,因为 OneDelegate 仅引用第一个而不是第二个。但是,有办法做到这一点吗?或者类似的东西?

PS1:我想要任意数量的 OneDelegate 声明,而不仅仅是一两个。

First, I was reading some forums and the help in MSDN and all says that a delegate can't be overloaded.

Now, I want to have something like this:

public delegate void OneDelegate();
public delegate void OneDelegate(params object[] a);

public void DoNothing(params object[] a) {}
public void DoSomething() { /* do something */ }

private OneDelegate someFunction;

someFunction = new OneDelegate(DoSomething);
someFunction = new OneDelegate(DoNothing);

So, like you know, you CAN'T do this, because OneDelegate only refers to the first one and not the second one. But, is there a way for doing this? or something like that?

PS1: I want to have any number of OneDelegate declarations, not just one or two.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

初与友歌 2024-10-01 06:10:26

想象一下这是可能的。假设我可以有一个重载的委托:

public delegate void OneDelegate(int i);
public delegate void OneDelegate(string s);

现在想象我声明一个这种类型的变量,然后为其分配一个函数,例如:

OneDelegate myDelegate = StringMethod;

其中 StringMethod 如此声明:

public void StringMethod(string s) { Console.WriteLine(s); }

现在您传递 myDelegate 到其他一些代码,该代码执行以下操作:

myDelegate(47);

您期望在这种情况下发生什么?运行时如何使用整数参数调用StringMethod()

如果您确实想要一个可以接受任何一组参数的委托,那么唯一的选择就是使用一个带有 params object[] 数组的委托:

public delegate void OneDelegate(params object[] parameters);

但是这样您就会必须为其分配一个实际上可以处理任何对象数组的函数,例如:

public void MyMethod(params object[] parameters)
{
    if (parameters == null || parameters.Length == 0)
        throw new ArgumentException("No parameters specified.");
    if (parameters.Length > 1)
        throw new ArgumentException("Too many parameters specified.");

    if (parameters[0] is int)
        IntMethod((int) parameters[0]);
    else if (parameters[0] is string)
        StringMethod((string) parameters[0]);
    else
        throw new ArgumentException("Unsupported parameter type.");
}

如您所见,这很快就会变得混乱。因此,我向您提出,如果您需要这样的委托,那么您可能在架构设计中的某个地方犯了错误。在继续实施之前识别此缺陷并修复设计,否则代码的可维护性将会受到影响。

Imagine for a moment this was possible. Suppose I could have an overloaded delegate:

public delegate void OneDelegate(int i);
public delegate void OneDelegate(string s);

Now imagine I declare a variable of this type and then assign a function to it, for example:

OneDelegate myDelegate = StringMethod;

where StringMethod is declared thusly:

public void StringMethod(string s) { Console.WriteLine(s); }

Now you pass myDelegate to some other code, and that code does this:

myDelegate(47);

What do you expect to happen in this case? How can the runtime call StringMethod() with an integer argument?

If you really want a delegate that can take any set of parameters at all, then the only option is to have one with a params object[] array:

public delegate void OneDelegate(params object[] parameters);

But then you will have to assign to it a function that can actually handle any object array, for example:

public void MyMethod(params object[] parameters)
{
    if (parameters == null || parameters.Length == 0)
        throw new ArgumentException("No parameters specified.");
    if (parameters.Length > 1)
        throw new ArgumentException("Too many parameters specified.");

    if (parameters[0] is int)
        IntMethod((int) parameters[0]);
    else if (parameters[0] is string)
        StringMethod((string) parameters[0]);
    else
        throw new ArgumentException("Unsupported parameter type.");
}

As you can see, this gets messy real quick. Therefore, I submit to you that if you need such a delegate, you have probably made a mistake somewhere in your architectural design. Identify this flaw and fix the design before you proceed with the implementation, as otherwise the maintainability of your code will suffer.

萌辣 2024-10-01 06:10:26

Action 类“执行此操作”。它是一个带有模板的委托,因此您可以拥有这样的委托:

public delegate void D<T>(params T[] arg);

func() {
    D<object> d1;
}

这可能与您将得到的最接近,即您需要一个模板类型作为参数。

编辑:根据评论,我猜您是在将委托传递给另一个函数之后。您也可以通过传递参数来完成它。不幸的是,如果不使用 fire 的 params 参数,你就无法做到这一点。

public void bar() {
    D<string> d = ...;
    fire(d, "first", "second");
    fire(d); // also works
}

public void fire<T>(D<T> f, params T[] args) {
    f(args);
}

The Action class "does this". It's a delegate with templates, so you can have a delegate like this:

public delegate void D<T>(params T[] arg);

func() {
    D<object> d1;
}

This is probably as close as you are going to get, i.e. you need a template type as a parameter.

Edit: Based on comments I guess you are after passing a delegate to another function. You can accomplish it by passing along the arguments as well. Unfortunately you cannot do this without the use of a params parameter to fire.

public void bar() {
    D<string> d = ...;
    fire(d, "first", "second");
    fire(d); // also works
}

public void fire<T>(D<T> f, params T[] args) {
    f(args);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文