2

別のアクション内にアクションを設定しようとしていますが、それに渡すアクションは最終的にはまだ null です。以下は簡単な例です:

Action<Action<VerifylocalResult>> docollectprint = (vl) =>
{
    vl = (vlocres) => 
                    {
                        //DoStuff
                    };

    //This returns false, indicating the action has been set:
    Console.WriteLine((vl == null).ToString()); 
};

//Hookups
docollectprint(vlocobj.Action_NotExists);

//This returns true, so the action has not been set:
Console.WriteLine((vlocobj.Action_NotExists==null).ToString()); 

実際の取引の代わりにゲッターメソッドを渡そうとしましたが、結果は同じです..最終的にはまだnullです。

Action<Func<Action<VerifylocalResult>>> docollectprint = (vl) =>
        {
            Action<VerifylocalResult> theaction = vl();
            theaction = (vlocres) => 
                {
                    //DoStuff
                };

            //This returns false, indicating the action has been set
            Console.WriteLine((theaction == null).ToString());
    };

//Hookups
docollectprint(() => { return vlocobj.Action_NotExists; });

    //This returns true, so the action has not been set
Console.WriteLine((vlocobj.Action_NotExists==null).ToString()); 

これを行う方法はありますか?また、これが以前に尋ねられた場合は申し訳ありませんが、検索したところ、やろうとしている人Action<ref string x>や同様のことしか見つかりませんでした.

更新(解決策):

Func<string, Action<VerifylocalResult>> docollectprint = (msg) =>
            {
        Action<VerifylocalResult> vl = (vlocres) => 
        {
            /*DoStuff*/
        };
                    return vl;
            };

    //Hookups
    vlocobj.Action_NotExists = docollectprint("x");
4

4 に答える 4

5

デフォルトでは、参照は値渡しされます。これは、参照に対する変更がローカルにのみ適用されることを意味します。渡された参照を変更しようとするのではなく、何かを返す必要があります。MSDN から:

  • キャプチャされた変数は、それを参照するデリゲートがスコープ外になるまでガベージ コレクションされません。
  • ラムダ式内で導入された変数は、外側のメソッドでは表示されません。

  • ラムダ式は、外側のメソッドから ref [VB の ByRef] または out パラメータを直接キャプチャすることはできません。

  • ラムダ式の return ステートメントは、外側のメソッドを返しません。

  • ラムダ式には、ターゲットが本体の外側または含まれる無名関数の本体内にある goto ステートメント、break ステートメント、または continue ステートメントを含めることはできません。

于 2012-12-21T14:23:29.613 に答える
3

すべてのアクションを取り除き、よりありふれたオブジェクトで同じ例を試してみましょう。あなたのコードは基本的に次のものと同等です:

Action<string> changeString = (s) =>
    {
        s = "result";
        Console.WriteLine(s);
    };

string myString = "someString" changeString(myString); //参照は値で渡され、機能しません changeString("someString"); //これは何をすべきか???

ただし、次の行に沿って、渡された値で何もしていないため、変更されたものを返すか、この場合は単に返すことができます。

Func<string> getString = () => return "result";

string myString = "someString";

myString = getString(); //works

またはあなたの場合:

Func<Action<VerifylocalResult>> docollectprint = () =>
    {
        return (vlocres) => 
        {
            //DoStuff
        };
    };

vlocobj.Action_NotExists = docollectprint();
于 2012-12-21T14:33:42.213 に答える
2

問題を解決するには、別のデリゲートを使用できます。まず、次のように宣言します。

delegate void RefAction<T>(ref T reference);

次に、メソッドをこれに変更します。

RefAction<Action<string>> docollectprint = (ref Action<string> vl) =>
{
    vl = vlocres =>
    {
        //DoStuff
    };
    //Action has been set
    Console.WriteLine((vl == null).ToString());
};

Action<string> action = null;
docollectprint(ref action);
//Action is still set
Console.WriteLine((action == null).ToString());

Funcもちろん、これは何らかの理由で使用したくない場合に備えてです。

于 2012-12-21T14:33:15.583 に答える
1

あなたが欲しいようですFunc<Action<VerifyLocalResult>>

Func<Action<VerifylocalResult>> docollectprint = (vl) =>
{
    vl = (vlocres) => 
    {
        //DoStuff
    };
    return vl;
};

その後、あなたはすることができます

vlocobj.Action_NotExists = docollectprint();
于 2012-12-21T14:30:13.557 に答える