2009-04-17 4 views
2

次の例では、実行時に定義する特定のメソッドを実行するSystem.Actionを定義しますが、メソッド名(またはメソッド自体)を渡すと、Actionメソッドでその特定のメソッドを指すデリゲート?私は現在、次のエラーを取得していますデリゲートをインスタンス化するためにメソッド名を渡すにはどうすればいいですか?

「methodNameのは、」「変数」ですが、あなたが好きな方法を渡すことはできません「メソッド」

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

    } 
} 

答えて

5

デリゲート宣言またはWriteMessageメソッドは必要ありません。以下を試してください:

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

    } 
} 

アクションはすでにデリゲートであるため、別のアクションを作成する必要はありません。

1

のように使用されますあなたが反射を使用しない限り。文字列の代わりにパラメータとしてWriteHandlerを使用してみませんか?

0

リフレクションで動作させることもできますが、これはお勧めできません。

なぜWriteMessageメソッドにWriteHandlerの引数を渡さないのですか?

次にあなたがこの(C#では2+)のようにそれを呼び出すことができます。引用符なし

WriteMessage(myMethod); 
2

パスを - に

Action<string> theFunction = WriteMessage(WriteBasic); 

変更 "WriteMessage" の署名 -

public static Action<string> WriteMessage(WriteHandler methodName) 

「プライベート」デリゲートを「public」に変更する -

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

あなたはDelegate.CreateDelegateが必要です。あなたの特定のケースでは、あなたがprobabaly Delegate.CreateDelegate(Type,Type,string)をしたい:

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

しかし、ムラデンミハイロビッチは尋ねたとして、なぜあなたは文字列に基づいてデリゲートを作成したいのですか?それはもっと簡単になり、コンパイラによってチェックされます! - メソッドから一致するシグネチャの代理者に暗黙的に変換するためのC#のサポートを使用する。

関連する問題