使用委托参数声明lambda

时间:2016-05-23 16:36:54

标签: c# .net lambda delegates

基本上我正在尝试理解WrapCallback

private static SendOrPostCallback WrapCallback(SendOrPostCallback sendOrPostCallback)
{
    return state =>
    {
        // do something
    };
}

此处使用了Statement LambdaDelegate

delegate void System.Threading.SendOrPostCallback(object state)

stateSendOrPostCallback委托的输入参数,它也是语句lambda的输入参数。但实际上这里返回的是什么?代表再次?怎么样?

我也试图做一个例子来更好地理解,但有些部分缺失了。只有 Hello 被写入控制台。

delegate void TestDelegate(string s);

public static void Main()
{
    TestDelegate del = new TestDelegate(Notify);
    del("Hello");
    WrapCallback(del);
}

private static void Notify(string name)
{
    Console.WriteLine(name);
}

private static TestDelegate WrapCallback(TestDelegate testDelegate)
{
    return s => {
        Console.WriteLine("test");
    };
}

有人可以向我解释WrapCallback的行为吗?

4 个答案:

答案 0 :(得分:1)

在您的示例代码中,WrapCallback正在返回委托

s => {
    Console.WriteLine("test");
};

在您的Main方法中,您正在调用WrapCallback,它返回该委托,但您不会对其执行任何操作,因此它永远不会向控制台打印任何内容。

如果您对Main方法进行了以下更改,则会打印" test"。

    public static void Main()
    {
        TestDelegate del = new TestDelegate(Notify);
        del("Hello");
        //Store the return value in a new delegate
        TestDelegate del2 = WrapCallback(del);
        //And then call that delegate.  Note that TestDelegate takes a string as a parameter
        del2("This string does nothing");
        //Alternatively, call the delegate at the same time it's returned, but don't store it
        WrapCallback(del)("This string does nothing");
    }

答案 1 :(得分:1)

WrapCallback返回一个函数(接受字符串参数s)。你仍然需要传递一个参数才能执行。

TestDelegate del2 = WrapCallback(del);
del2("something"); //prints "test"

答案 2 :(得分:1)

好吧,让我们想一想场景 - 在我们做某事之前,我们需要在控制台中显示“操作已启动”,然后我们想做一些操作并最终显示:“操作已完成”。

我们可以使用与您的示例中此SendOrPostCallback中使用的逻辑非常接近的逻辑来实现此目的。为简单起见,我们的业务操作是计算数字的平方。代码是:

    static Action<object> WrapOperation(Action<object> action)
    {
        return new Action<object>(
            obj =>
        {
            Console.Write("Operation is started  ");
            Thread.Sleep(1500);

            action.Invoke(obj);

            Thread.Sleep(1500);
            Console.Write("   " + "Operation is finished");
        });
    }

主要是:

        Action<object> someBusinessOperation = x => Console.Write((int)x * (int)x);

        Action<object> wrappedOperation = WrapOperation(someBusinessOperation);

        wrappedOperation(9);

        Console.ReadKey();

输出:Operation is started 81 Operation is finished

那么这里发生了什么?

---在这行代码中我们创建了函数:

Action<object> someBusinessOperation = x => Console.WriteLine((int)x * (int)x);

--- WrapOperation方法只接受委托作为参数,然后创建并返回一个新的委托实例。请注意,对于这一点,我们尚未调用任何方法,我们只是让WrapOperation包装委托并返回另一个委托。

最后,我们使用该委托调用方法并传递参数:

wrappedOperation(9);

P.S。

当我们将9传递给wrappedOperation时,它会在方法中作为obj参数注入,此方法执行它自己的逻辑,然后通过委托someBusinessOperation方法重新使用({{1} }}并将此对象作为x => Console.Write((int)x * (int)x)传递给此函数。因此,我们创建的函数接受对象,但在调用x之前和之后做一些额外的逻辑,而不只是一个接受对象作为参数的函数。

值得一提的是,当我们在lambda中使用参数someBusinessOperation时,我们使用名为 closure 的东西(从外部范围捕获变量)

答案 3 :(得分:1)

  

但实际上这里返回了什么?代表再次?

不是 委托,但会返回委托。旧代表被丢弃了。

这是一个更简单的重写:

private static TestDelegate WrapCallback(TestDelegate testDelegate /*ignored*/)
{
    TestDelegate result = (s => {
        Console.WriteLine("test");
    });
    return result;
}