简体   繁体   中英

What is wrong with this lambda expression?

I am really struggling to understand why, when I change my code to use a lamdba expression, it doesn't work.

This code works and prints on console:

object dummy = new object();
InterServer.ExecuteDataReader(new InterServerRequest(ServerID.a_01, "dbo.getbooks") 
    { 
        Params = new Dictionary<string, object> { 
            { "Tool", "d1" }, 
            { "Loc", locale == string.Empty ? null : locale } } 
    },
    (_, reader) =>
        {
            reader.AsEnumerable(r => (r.GetString(r.GetOrdinal("book")))).ToList().ForEach(Console.WriteLine);
            return new Response(dummy);
        }
    );

This code has been changed to use a lambda expression; it doesn't print anything, I don't understand why:

InterServer.ExecuteDataReader(new InterServerRequest(ServerID.a_01, "dbo.getbooks")
    { 
        Params = new Dictionary<string, object> { 
            { "Tool", "d1" }, 
            { "Loc", locale == string.Empty ? null : locale } } 
    },
    (_, reader) =>
        {
            return new Response(new Action(() => 
                reader.AsEnumerable(r =>(r.GetString(r.GetOrdinal("book")))).ToList().ForEach(Console.WriteLine)));
        }
    );

This is really driving me mad as I don't see if I am doing anything wrong. Can someone help?

Thanks, AG

What are you trying to achieve by making it use a lambda expression?

In this example, the Action is not invoked, therefore nothing happens. When the Action will be invoked you'll see the output.

The Action is not executed implicitly.

For example:

public void Call()
{
    // Call with int argument 1
    DoSomething(1);

    // Call with Func that returns 1
    // It'll never produce the value unless Func is invoked
    DoSomething(new Func<int>(() => 1));

    // Call with Func explicitly invoked
    // In this case the body of the lambda will be executed
    DoSomething(new Func<int>(() => 1).Invoke());
}

public void DoSomething(object obj)
{

}

Calling the Response constructor with Action will actually send the Action . If Response has an overload that invokes it and uses the return value, then the Action will appear only when the Response actually uses it (not necessary during the constructor call).

In your example, the work will be done anyway during the call to (_, reader) => ... so there is no work done "too early".

To make it clear (last sample I add :) ):

public void Call()
{
    DoSomething(new Action(() => Console.WriteLine("Arrived")));
}

public void DoSomething(Action obj)
{
    int x = 0; // Nothing printed yet
    Action storedAction = obj; // Nothing printed yet
    storedAction.Invoke(); // Message will be printed
}

Unless Response expects an Action it'll never get to execute its body.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM