2

我试图在另一个动作中设置一个动作,但我传递给它的动作最终仍然为空。这是一个愚蠢的例子:

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

我已经尝试过传递一个getter方法而不是真正的交易,但结果是一样的..它最终仍然是空的。

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:

  • 在引用它的委托超出范围之前,不会对捕获的变量进行垃圾收集。
  • 在 lambda 表达式中引入的变量在外部方法中不可见。

  • lambda 表达式不能直接从封闭方法中捕获 ref [ByRef in VB] 或 out 参数。

  • lambda 表达式中的 return 语句不会导致封闭方法返回。

  • lambda 表达式不能包含 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 回答