2009-09-05 17 views
8
private void StringAction(string aString) // method to be called 
{ 
    return; 
} 

private void TestDelegateStatement1() // doesn't work 
{ 
    var stringAction = new System.Action(StringAction("a string")); 
    // Error: "Method expected" 
} 

private void TestDelegateStatement2() // doesn't work 
{ 
    var stringAction = new System.Action(param => StringAction("a string")); 
    // Error: "System.Argument doesn't take 1 arguments" 

    stringAction(); 
} 

private void TestDelegateStatement3() // this is ok 
{ 
    var stringAction = new System.Action(StringActionCaller); 

    stringAction(); 
} 

private void StringActionCaller() 
{ 
    StringAction("a string"); 
} 

TestDelegateStatement3作品が、TestDelegateStatement1が失敗した理由を私は理解していない表現します。いずれの場合も、Actionには、ゼロパラメータを取る方法が用意されています。彼らはaString)を取るメソッドを呼び出すかもしれませんが、それは無関係でなければなりません。彼らはパラメータを取らない。これはラムダ式ではできませんか?何か間違っていますか?混乱が

答えて

18

あなたが言ったように、Actionにはパラメータはありません。 あなたが行う場合は、この:それはメソッドのパラメータではありませんので、あなたが実際に、ここでメソッドを実行

var stringAction = new System.Action(StringAction("a string")); 

あなたが行う場合は、この:

var stringAction = new System.Action(param => StringAction("a string")); 

あなたのメソッドはアクションがないparamと呼ばれるパラメータを、取ることを知らせます。

だから、これを行うには正しい方法は次のようになります。

var stringAction = new System.Action(() => StringAction("a string")); 

以上のコンパクト:

Action stringAction =() => StringAction("a string"); 

空のブラケットは、ラムダがパラメータを取らない示すために使用されています。

+0

@Botz:分だから、
new Action<string>(myStringParam => StringAction(myStringParam));

、あなたのケースでは、完全なコードは次のようになります。 (コンパイラは 'var'が' System.Action 'であることを知るのに十分な情報がありません) ')。 – devuxer

+0

ああ、ありがとう。これを修正しました。 – Botz3000

2

C#2.0では、Action代理人は、パラメータを受け入れないvoid代理人です。 それ以降のバージョンでは、汎用のAction<T>代理人があります。ここで、Tはパラメータの種類を示します。

これは動作するはずです:

var stringAction = new Action<string>(param => StringAction(param)); 

またはより良い:

var stringAction = new Action<string>(StringAction); // using method group conversion 

そして、あなたは

stringAction("Hello world"); 
4

を呼び出すことができ、私はこの上の専門家ではないんだけど、あなたを持っていますこれを試した?

4

Action代理人は、パラメータを持たず、voidを返すメソッドの代理人として定義されます。
1.メソッドを呼び出そうとしていますが、パラメータを取得しようとしています。
2.メソッドを呼び出していて、それをパラメータとして与えていません(新しいAction(methodName) )、1のせいで動作しませんでした。サンプル2では

、あなたは再び同じ過ちを作っている、あなたのラムダは、パラメータを取っている、あなたはこのようにそれを書くべきでは:
new Action(() => StringAction("a string"));

あなたがデリゲートを作成する場合は、パラメータを取ります、あなたはこのようにそれを実行する必要があります。


private void StringAction(string aString) // method to be called 
{ 
    return; 
} 

private void TestDelegateStatement1() // now it works 
{ 
    var stringAction = new Action<string>(StringAction); 
    //You can call it now: 
    stringAction("my string"); 
} 

private void TestDelegateStatement2() // now it works 
{ 
    var stringAction =() => StringAction("a string"); 
    //Or the same, with a param: 
    var stringActionParam = (param) => StringAction(param); 

    //You can now call both: 
    stringAction(); 
    stringActionParam("my string"); 
} 

private void TestDelegateStatement3() // this is ok 
{ 
    var stringAction = new System.Action(StringActionCaller); 

    stringAction(); 
} 

private void StringActionCaller() 
{ 
    StringAction("a string"); 
}