C# - How can I "overload" a delegate?
Solution 1
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.
Solution 2
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);
}
Lucas Gabriel Sánchez
I'm a programmer. I've been a programmer for over a decade. I've love languages, I like to learn them and use as many as I can, and in no particular order these are the ones I used in my career: Action Script 3, for flash games C#, for Unity 3D games C++, for mobile games with cocos2d-x, and apps with JUCE Java, for Android games and apps, and for desktop apps a long time ago Objective-C, for iOS games and apps JavaScript, for Web and web services (nodejs) Go, for web services Python (2.x and 3.x), for internal tools and game servers I like to play around with different languages to build things and find interesting facts about programming, so I'm developing a new programming language (duh!) in a very slow pace, not only to create something, but also to learn the hows and whys of this lovely profession. The languages I'm interested or learning right now: Lisp, Erlang and Elixir
Updated on April 21, 2020Comments
-
Lucas Gabriel Sánchez about 4 years
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.