C#でパラメータとして関数を渡す方法?

c# reflection

C#のパラメータとして関数を渡すことは可能ですか? FuncまたはActionクラスを使ってそれを行うことができますが、これは私に関数シグネチャ全体を一度に宣言することを強制します。 Delegateを使用しようとすると、メソッドグループをDelegateに変換できないというコンパイルエラーが発生します。

私は Axialに取り組んでおり、ユーザーがWebサービスを呼び出せるようにしています。 私がやろうとしているのは、Visual Studioプロキシクラスを作成してから生成された関数を渡す機能です。 生成されたコードは関数名のみを使用するため、関数のシグネチャは関係ありません。 ただし、プロキシのUrlプロパティを使用する機能と、Webサービスが存在しないかVisual Studioで更新された場合のコンパイラエラーという2つの理由から、名前の代わりに関数を渡したいのです。

public void AlertIt(オブジェクトo){Axial.DOM.Window.Alert(o.ToString()); } public void CallAddService(){object [] param = new object [] {int.Parse(txtA.Text)、int.Parse(txtB.Text)};} Axial.ServerScript.CallWebService(new WSProxy.WS()。追加、param、AlertIt、AlertIt); }

Axial.ServerScript {public void CallWebService(デリゲートメソッド、オブジェクト[]パラメータ、アクションsuccessCallback、アクションfailureCallback){// javascriptに変換します(既に機能しています)}}

  55  23


ベストアンサー

私はあなたが欲しいものはだと思います:

静的オブジェクトInvokeMethod(デリゲートメソッド、パラメータ[]引数){return method.DynamicInvoke(args); }

static int Add(int a、int b){a bを返す。 }

static void Test(){Console.WriteLine(InvokeMethod(new Func(Add)、5、4)); }

“9”を印刷します。

52


メソッドグループ、無名メソッド、またはラムダ式をデリゲートに変換するには、コンパイラが正確なデリゲートタイプを知っている必要があります。 ただし、これをより簡単にするために、ラムダ式とキャプチャされた変数を使用することもできます。

public void InvokeMethod(Action action)
{
    action();
}

public int Add(int a, int b)
{
    return a + b;
}

public void Test()
{
    InvokeMethod(() => Add(2, 3));
}

これは基本的に通常の呼び出しを遅らせますが、実際の Add`呼び出しをプレーンな Action`デリゲートにラップすることで行います。

それがあなたの要求を満たさないならば、おそらくあなたは私達があなたが本当に達成しようとしていることについてもう少し私達に言うことができます。

編集:これが生成されたコードであれば、正しい型引数を使って `Func <…​>`にキャストすることができます。 それ以外に、メソッドグループを渡すだけの本当の方法はありません。 “infoof(…​)”演算子(typeofのように、メンバーのために)を呼び出すことが時々あります。これはあなたにMemberInfoを与えるでしょうが、それは実際には存在しません。

46


あなたは最初に代理人を持つべきです

int型デリゲート操作(int a、int b)

それからなる:

public void InvokeMethod(操作メソッド、オブジェクトターゲット、オブジェクトパラメータ){method((int)target、(int)param); }

Invokeを呼び出す必要はありません。

dboneと同じように、なぜparams []配列が必要になるのかよくわかりません。 paramsの拡張された使用法を明確にしますか?

また、私はあなたの質問の中で何かを訂正しなければならないでしょう、なぜならそれはコンパイルエラーを引き起こすでしょう:p

4


こちらのデリゲートの使い方をご覧ください。

http://www.c-sharpcorner.com/UploadFile/Ashush/Delegates02152008155757PM/Delegates.aspx[Delegateの例]

なぜあなたはリフレクションを使っていますか? 異なる数のパラメータが存在することがありますか? または、メソッドsigntureが一定のままであることを知っていますか(C#がparams []キーワードをサポートしていることも忘れないでください)

http://msdn.microsoft.com/en-us/library/w5zay9db(VS.71).aspx[params c#]

HTH

骨格

3


Justin Etheredgeによる 関数型プログラミングシリーズを参照してください。 あなたはそこにあなたの問題に対する解決策を見つけるべきです。

3


これは(* C / C /VB.NET/Python )スタイルの*ポインター/参照(* C#デリゲート付き)による関数のパスに既に慣れているプログラマーにとっては非常に単純な例です。

void CALLBACK(String s)を委任します。 static void Main(string [] args){

Get( "some string"、testfunc);

Util.pause(); }

static void Get(String s、CALLBACK x){x(s); }

static void testfunc(String s){Console.WriteLine(s); }

3


あなたがさらなる処理のために戻り値をキャッチする必要があるのと同様に、パラメータとしてメソッドを渡す必要があるなら、言いなさい。 それから上記の例はうまくいくでしょう。 しかし、void型の戻り値を持つメソッドを渡す必要がある場合は、InvokeMethod関数をもう1つ作成する必要があります。 以下の例を確認してください。

private static T retry(メソッドのデリゲート、params object [] args){(int i = 0; i <= 3; i){try {return(T)method.DynamicInvoke(args);} catch(Exception ex){if(i == 3){logMessage(ex.Message);} Console.WriteLine( "再試行回数" i); Thread.Sleep(10);デフォルト(T)を返します。 }

private static void retry2(メソッドのデリゲート、params object [] args){(int i = 0; i <= 3; i){try {method.DynamicInvoke(args);ブレーク; catch(Exception ex){if(i == 3){logMessage(ex.Message);} //デフォルト値(T)を返します。 Console.WriteLine( "再試行回数" i); Thread.Sleep(10); static bool isSuccess = true; static void logMessage(string msg){isSuccess = false;} Console.WriteLine(msg); }

static int Add(int a、int b){a bを返す。 }

static void Add2(int a、int b){int c = a b; Console.WriteLine(c); }

static void Main(string [] args){int d =再試行(new Func(Add)、6、7.7); Console.Write( "" d "\ n" isSuccess);

retry2(新しいアクション(追加2)、45、60)。

Console.ReadKey(); }

2


このようなものはあなたのために働くべきです:

int MyDelegate(int a、int b)をデリゲートします。 public int Add(int a、int b){a bを返す。 InvokeMethod(デリゲートメソッド、オブジェクト[]パラメータ){Console.WriteLine(method.DynamicInvoke(param));} } public Form1(){InitializeComponent();} InvokeMethod(new MyDelegate(Add)、新しいオブジェクト[] {1、2}); }

がんばろう!

1


タイトルとURLをコピーしました