2009-04-17 7 views
2

Dans l'exemple suivant, je souhaite définir System.Action qui exécute une méthode spécifique que je définis à l'exécution, mais comment puis-je transmettre le nom de la méthode (ou la méthode elle-même) afin que la méthode Action puisse définir déléguer pour désigner cette méthode particulière?Comment passer un nom de méthode afin d'instancier un délégué?

Je reçois actuellement l'erreur suivante:

« methodName » est une « variable » mais est utilisé comme une « méthode »

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); 
     } 

    } 
} 

Répondre

5

Vous n'avez pas besoin de la déclaration Delegate ou de la méthode WriteMessage. Essayez ce qui suit:

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 est déjà un délégué, vous n'avez donc pas besoin d'en créer un autre.

1

Vous ne pouvez pas passer la méthode comme à moins que vous n'utilisiez la réflexion. Pourquoi ne pas prendre un WriteHandler comme paramètre à la place d'une chaîne?

0

Vous pouvez le faire fonctionner avec la réflexion, mais ce n'est pas recommandé. Pourquoi ne pas faire que la méthode WriteMessage prenne un argument de WriteHandler?

Ensuite, vous pouvez l'appeler comme celui-ci (en C# 2+):

WriteMessage(myMethod); 
2

Faites passer sans les guillemets -

Action<string> theFunction = WriteMessage(WriteBasic); 

Modifier la signature de "WriteMessage" à -

public static Action<string> WriteMessage(WriteHandler methodName) 

Modifier également le délégué "privé" en "public" -

public delegate void WriteHandler(string message); //Edit suggested by Mladen Mihajlovic 
0

Vous souhaitez Delegate.CreateDelegate. Dans votre cas, vous voulez probabaly Delegate.CreateDelegate(Type,Type,string):

 
public static Action<string> WriteMessage(string methodName) 
{ 
    return (Action<string>) Delegate.CreateDelegate (
     typeof(Action<string>), 
     typeof(Program), 
     methodName); 
} 

Cependant, comme Mladen Mihajlovic a demandé, pourquoi voulez-vous créer un délégué basé sur une chaîne? Ce serait beaucoup plus facile - et vérifié par le compilateur! - utiliser le support de C# pour la conversion implicite des méthodes en délégués d'une signature correspondante.

Questions connexes