传递动作作为参考

时间:2012-12-21 14:21:14

标签: c# lambda

我正在尝试在另一个Action中设置一个Action,但我传递给它的Action最终仍为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()); 

我已经尝试过传递一个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 个答案:

答案 0 :(得分:5)

默认情况下,引用按值传递。这意味着对引用的任何更改仅限于本地范围。你应该返回一些东西而不是试图改变传入的引用。来自MSDN:

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

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

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

  • lambda表达式不能包含goto语句,break语句, 或继续声明其目标在身体外或身体内 包含匿名函数的主体。

答案 1 :(得分: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();

答案 2 :(得分: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

答案 3 :(得分:1)

您似乎想要Func<Action<VerifyLocalResult>>

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

然后你可以做

vlocobj.Action_NotExists = docollectprint();