I tried to define a delegate override between Int32
and IntPtr
. Why are the following overloads illegal?
public delegate int EnumWindowsCallback (System.IntPtr hWnd, int lParam);
public delegate int EnumWindowsCallback (System.IntPtr hWnd, System.IntPtr lParam);
That looks pretty strange. They are both structs but are different and implement from different interfaces.
Come to think of it, I have never tried to overload a delegate before. Is it even legal, and if so, why?
UPDATE: After going through the answers and some more SO posts, I was baffled that delegates cannot be declared even with a varying number of parameters. I am still wondering why this cannot be resolved at runtime.
All delegate types are limited to a single
.Invoke
method. I'm not sure what exactly the Framework would do if one were to use CIL to define a type which derived fromDelegate
and included multiple overloads ofInvoke
, but an expectation that only oneInvoke
method will exist is pretty well backed into the Framework.What one may be able to do, however, is define an interface which one can use in place of the delegate type. For example, one could define something like:
in which case code which had a reference to something that implemented
InvokableAsOptionalGeneric
could either call it without parameters, or with a parameter of any type; the latter form could be used with value-type arguments without boxing (whereas anAction<Object>
would have to box the parameter). Note that for any interface of the above style, one could define a class with a static method similar toDelegate.Combine
that would work with any objects that implement the interface; every such interface would need its own "combining" class, though much of the code would be boilerplate.I don't like those people who always say "no, you can't". ;-)
Therefore my answer is: yes, you can!
Originally I wanted to call an overloaded non-generic method from a generic-method. The compiler didn't like that. Possible solutions are in SO 5666004 and SO 3905398, but I found them to be quite complicated.
After having read this and other posts and articles, I had some blurred idea in the back of my mind. Trial and error, and learing new functions got me to a working solution.
The others are right, you cannot overload normal delegates, because each delegate has it's individual type and uses static binding.
But you can use the abstract
Delegate
class and dynamic binding.Here's the ready-to-compile-and-run solution (written in C++/CLI):
No, you cannot overload a delegate. Overloads are selected when there is type information available to the compiler to pick one... but with a delegate, you are supplying the type information and the compiler would have no way to select from overloads.
If you want a family of similar delegate types, you can use generics.
Now you can define overloaded p/invoke signatures which accept different delegate types
EnumWindowsCallback<int>
,EnumWindowsCallback<IntPtr>
, etc.No, it's not legal. You're currently declaring two types with the same fully-qualified name.
The only thing that looks a bit like overloading when it comes to types is if you declare two types which differ in the number of generic type parameters. For example,
Action<T>
,Action<T1, T2>
etc. The rules for delegates are no different than the rules for other types here.So either you need to declare one generic delegate (and use different type arguments), or use two different type names.