tags:

views:

330

answers:

5

In the following example, I want to define a System.Action which executes a specific method that I define at runtime, but how do I pass the method name (or the method itself) so that the Action method can define the delegate to point to that particular method?

I'm currently getting the following error:

'methodName' is a 'variable' but is used like a 'method'

using System;
using System.Collections.Generic;

namespace TestDelegate
{
    class Program
    {
        private delegate void WriteHandler(string message);

        static void Main(string[] args)
        {
            List<string> words = new List<string>() { "one", "two", "three", "four", "five" };
            Action<string> theFunction = WriteMessage("WriteBasic");

            foreach (string word in words)
            {
                theFunction(word);
            }
            Console.ReadLine();
        }

        public static void WriteBasic(string message)
        {
            Console.WriteLine(message);
        }

        public static void WriteAdvanced(string message)
        {
            Console.WriteLine("*** {0} ***", message);
        }

        public static Action<string> WriteMessage(string methodName)
        {
            //gets error: 'methodName' is a 'variable' but is used like a 'method'
            WriteHandler writeIt = new WriteHandler(methodName);

            return new Action<string>(writeIt);
        }

    }
}
+1  A: 

You can't pass the method like that unless you use reflection. Why not take a WriteHandler as your parameter instead of a string?

Adam Robinson
A: 

You could make it work with reflection, but that is not recommended.

Why not make the WriteMessage method take an argument of WriteHandler?

Then you can call it like this (in C# 2+):

WriteMessage(myMethod);
Skurmedel
+2  A: 

Pass it without quotes -

Action<string> theFunction = WriteMessage(WriteBasic);

Change the signature of "WriteMessage" to -

public static Action<string> WriteMessage(WriteHandler methodName)

Also change the "private" delegate to "public" -

public delegate void WriteHandler(string message); //Edit suggested by Mladen Mihajlovic
Kirtan
+4  A: 

You don't need the Delegate declaration or the WriteMessage method. Try the following:

using System;
using System.Collections.Generic;

namespace TestDelegate
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string>() { "one", "two", "three", "four", "five" };
            Action<string> theFunction = WriteBasic;

            foreach (string word in words)
            {
                theFunction(word);
            }
            Console.ReadLine();
        }

        public static void WriteBasic(string message)
        {
            Console.WriteLine(message);
        }

        public static void WriteAdvanced(string message)
        {
            Console.WriteLine("*** {0} ***", message);
        }

    }
}

Action is already a delegate so you don't need to make another one.

Mladen Mihajlovic
A: 
jonp