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):
using namespace System;
using namespace System::Collections::Generic;
using namespace System::Threading;
delegate void DelegateVI (int);
delegate void DelegateVB (bool);
delegate void DelegateVAUC (array<unsigned char>^);
ref class CWorker
{
public:
void DoWork (int i_iValue)
{
Console::WriteLine ("int");
Thread::Sleep (500);
}
void DoWork (bool i_bValue)
{
Console::WriteLine ("bool");
Thread::Sleep (1000);
}
void DoWork (array<unsigned char>^ i_aucValue)
{
Console::WriteLine ("array<uc>");
Thread::Sleep (2000);
}
};
generic <class T>
ref class CData
{
public:
CData (int i_iSize, CWorker^ i_oWorker)
{
m_aData = gcnew array<T>(i_iSize);
if (T::typeid == int::typeid)
{
Reflection::MethodInfo^ oMethod = CWorker::typeid->GetMethod("DoWork", gcnew array<Type^>{int::typeid});
m_delDoWork = Delegate::CreateDelegate (DelegateVI::typeid, i_oWorker, oMethod);
}
else if (T::typeid == bool::typeid)
{
Reflection::MethodInfo^ oMethod = CWorker::typeid->GetMethod("DoWork", gcnew array<Type^>{bool::typeid});
m_delDoWork = Delegate::CreateDelegate (DelegateVB::typeid, i_oWorker, oMethod);
}
if (T::typeid == array<unsigned char>::typeid)
{
Reflection::MethodInfo^ oMethod = CWorker::typeid->GetMethod("DoWork", gcnew array<Type^>{array<unsigned char>::typeid});
m_delDoWork = Delegate::CreateDelegate (DelegateVAUC::typeid, i_oWorker, oMethod);
}
}
void DoWork (CWorker^ i_oWorker)
{
m_delDoWork->DynamicInvoke (gcnew array<Object^>{m_aData[0]});
// i_oWorker->DoWork (m_aData[0]); //--> fails with compiler error C2664: cannot convert argument...
}
array<T>^ m_aData;
Delegate^ m_delDoWork;
};
int main()
{
CWorker^ oWorker = gcnew CWorker;
CData<bool>^ oData = gcnew CData<bool>(3, oWorker);
oData->DoWork (oWorker);
}