2009-04-17 7 views
2

Im folgenden Beispiel möchte ich eine System.Action definieren, die eine bestimmte Methode ausführt, die ich zur Laufzeit definiere, aber wie übermittele ich den Methodennamen (oder die Methode selbst), so dass die Action-Methode die definieren kann delegieren, um auf diese bestimmte Methode zu verweisen?Wie Übergeben eines Methodennamens, um einen Delegaten zu instanziieren?

Ich bin derzeit die folgende Fehlermeldung erhalten:

‚Methodenname‘ ist ein ‚Variable‘, sondern ist wie eine ‚Methode‘ verwendet

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

    } 
} 

Antwort

5

Sie benötigen die Delegate-Deklaration oder die WriteMessage-Methode nicht. Versuchen Sie Folgendes:

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

    } 
} 

Aktion ist bereits ein Delegat, so dass Sie keine weitere erstellen müssen.

1

Sie nicht die Methode übergeben kann, wie das, es sei denn, Sie verwenden Reflexion. Warum nicht einen WriteHandler als Parameter anstelle einer Zeichenfolge verwenden?

0

Sie könnten es mit Reflexion arbeiten lassen, aber das wird nicht empfohlen.

Warum nicht die WriteMessage-Methode ein Argument von WriteHandler nehmen?

Dann können Sie es so nennen (in C# 2 +):

WriteMessage(myMethod); 
2

Direkt ohne Anführungszeichen -

Action<string> theFunction = WriteMessage(WriteBasic); 

Ändern Sie die Unterschrift von "Writemessage" zu -

public static Action<string> WriteMessage(WriteHandler methodName) 

Ändern Sie auch den "privaten" Delegaten zu "public" -

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

Sie möchten Delegate.CreateDelegate. In Ihrem speziellen Fall, Sie probabaly Delegate.CreateDelegate(Type,Type,string) wollen:

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

Doch wie Mladen Mihajlovic gefragt, warum tun Sie einen Delegaten auf eine Zeichenfolge basierend erstellen? Es wäre viel einfacher - und vom Compiler überprüft! - Verwendung der C# - Unterstützung für die implizite Konvertierung von Methoden in Delegaten einer passenden Signatur.

Verwandte Themen