views:

162

answers:

5

Hello,

If I have a delegate and a method

public delegate void SomeDelegate(String p);

void aMethod(String p) {
}

And then I try to invoke this on a new thread like so

SomeDelegate sd = new SomeDelegate(aMethod());
sd.BeginInvoke("heyhey", callBack, null)

The BeginInvoke method call now accepts a string as the first parameter, however, if I remove the "String p" from the delegate and the aMethod(), BeginInvoke now only requires two parameters.

How can I build a function like BeginInvoke that dynamically accepts different types of parameters based on code elsewhere?

Sorry If Im being vague here but I've never seen this before and I'm very curious.

A: 

This is called method overloading. You can find a tutorial here.

EDIT:

Then I probably misunderstood your question.

If you a looking how to accept different parameters without overloading you use:

public void MyMethod(params object[] args)
{
  foreach (object o in args)
  {
    Type t=o.GetType();
    // do something with o depending on the type
    if (t==typeof(int))
    {
      int i=(int)o; 
      // ...
    }
    else if (t==typeof(string)) // etc.
    {
    }
  }
}

You can then call:

MyMethod(5, "foo", 7.77);
MyMethod("foo", "bar");
// etc.
chris
I know what overloading is, but this is different.
Vince
+3  A: 

I believe that is Intellisense doing it's job for delegates.

You could probably define a method with the params keyword to have a method accept a variable amount of parameters, but until C# 4.0 is released (it has optional and named parameters), I'm not sure you can do stuff like that yourself.

Of course, I could be wrong.

SirDemon
A: 

It's not quite clear what you want to do. If you want to know how to create a new delegate with different parameters you do it as:

public delegate void SomeDelegate(String p, string q);
private static void aMethod(string p, string q) 
{
    Console.WriteLine(p + q);
}

and to use the delegate:

SomeDelegate sd = new SomeDelegate(aMethod);
sd.BeginInvoke("heyhey", "yoyo" callback, null);

If on the other hand you want to start a new thread by calling a method without having a previously defined delegate you can use:

ThreadPool.QueueUserWorkItem(delegate { aMethod("heyhey", "yoyo"); });
sipwiz
+4  A: 

I think what you're missing is the fact that the Invoke/BeginInvoke/EndInvoke methods aren't defined on Delegate - they're automatically generated for the delegate type by the compiler.

When you originally declare

public delegate void SomeDelegate(String p);

the compiler generates:

public class SomeDelegate : Delegate
{
    public SomeDelegate(Object target, IntPtr method) { ... }

    public virtual IAsyncResult BeginInvoke(string p, 
        AsyncCallback callback, object @object) { ... }

    public virtual void EndInvoke(IAsyncResult result) { ... }

    public virtual void Invoke(string p) { ... }
}

(with appropriate method bodies, attributes etc).

When you change the signature of SomeDelegate to remove the parameter, the generated type changes to:

public class SomeDelegate : Delegate
{
    public SomeDelegate(Object target, IntPtr method) { ... }

    public virtual IAsyncResult BeginInvoke(
        AsyncCallback callback, object @object) { ... }

    public virtual void EndInvoke(IAsyncResult result) { ... }

    public virtual void Invoke() { ... }
}

There's nothing really dynamic going on - you changed the signature of SomeDelegate, and that changes the signature of SomeDelegate.BeginInvoke. Nothing mysterious.

Jon Skeet
A: 

This is not something you can do. You are not as powerful as the compiler!

M. Jahedbozorgan