Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7710185
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T01:03:36+00:00 2026-06-01T01:03:36+00:00

I was curious in what ways the compiler handled lambdas declared in loops. I’ve

  • 0

I was curious in what ways the compiler handled lambdas declared in loops. I’ve had a few cases where I’ve declared lambdas inline so that I can use variables local to the calling method within the lambda. I’ve included two examples below.

Will the compiler create N delegates for a lambda within a loop? What (and which) optimizations can the compiler make in such cases? Additionally, MSDN mentions to use lambdas over anonymous functions, but doesn’t go into depth as to why. So, why?

Example 1:

public static class MethodPlayground1
{
    public static void TestMethod()
    {
        for (int i = 1; i <= 12; i++)
        {
            int methodLocal1 = i;
            string methodLocal2 = i.ToString();
            KeyValuePair<int, string> methodLocal3 = new KeyValuePair<int, string>(i, i.ToString());
            // Case A
            ThreadPool.QueueUserWorkItem((state) =>
            {
                int threadLocal1 = methodLocal1 + 1;
                string threadLocal2 = methodLocal2 + " o'clock";
                int threadLocal3 = methodLocal3.Key + 2;
                string threadLocal4 = methodLocal3.Value + " oranges";
            });
            // Case B
            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                int threadLocal1 = methodLocal1 + 1;
                string threadLocal2 = methodLocal2 + " o'clock";
                int threadLocal3 = methodLocal3.Key + 2;
                string threadLocal4 = methodLocal3.Value + " oranges";
            });
            // Case C
            ThreadPool.QueueUserWorkItem((state) =>
            {
                int threadLocal1 = methodLocal1 + 1;
                string threadLocal2 = methodLocal2 + " o'clock";
                int threadLocal3 = methodLocal3.Key + 2;
                string threadLocal4 = methodLocal3.Value + " oranges";
            });
            // Case D
            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                int threadLocal1 = methodLocal1 + 1;
                string threadLocal2 = methodLocal2 + " o'clock";
                int threadLocal3 = methodLocal3.Key + 2;
                string threadLocal4 = methodLocal3.Value + " oranges";
            });
            // Case E
            ThreadPool.QueueUserWorkItem(AsyncMethod, new object[] { methodLocal1, methodLocal2, methodLocal3 });
        }
    }
    private static void AsyncMethod(object state)
    {
        object[] methodArgs = (object[])state;
        int methodArg1 = (int)methodArgs[0];
        string methodArg2 = (string)methodArgs[1];
        KeyValuePair<int, string> methodArg3 = (KeyValuePair<int, string>)methodArgs[2];

        int threadLocal1 = methodArg1 + 1;
        string threadLocal2 = methodArg2 + " o'clock";
        int threadLocal3 = methodArg3.Key + 2;
        string threadLocal4 = methodArg3.Value + " oranges";
    }
}

Example 2:

public static class MethodPlayground2
{
    private static int PriorityNumber;
    public static void TestMethod()
    {
        List<int> testList = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7 });
        for (int i = 1; i <= 7; i++)
        {
            // Case A
            testList.Sort((i1, i2) =>
            {
                if ((i1 == i) || (i2 == i))
                {
                    if (i1 == i2) return 0;
                    else if (i1 == i) return -1;
                    else return 1;
                }
                else return i1.CompareTo(i2);
            });
            // Case B
            testList.Sort(delegate(int i1, int i2)
            {
                if ((i1 == i) || (i2 == i))
                {
                    if (i1 == i2) return 0;
                    else if (i1 == i) return -1;
                    else return 1;
                }
                else return i1.CompareTo(i2);
            });
            PriorityNumber = i;
            // Case C
            testList.Sort(IntCompareWithPriority1);
            // Case D
            testList.Sort(IntCompareWithPriority2);
            // Case E
            testList.Sort(IntCompareWithPriority3);
        }
    }
    private static Comparison<int> IntCompareWithPriority1 = (i1, i2) =>
    {
        if ((i1 == PriorityNumber) || (i2 == PriorityNumber))
        {
            if (i1 == i2) return 0;
            else if (i1 == PriorityNumber) return -1;
            else return 1;
        }
        else return i1.CompareTo(i2);
    };
    private static Comparison<int> IntCompareWithPriority2 = delegate(int i1, int i2)
    {
        if ((i1 == PriorityNumber) || (i2 == PriorityNumber))
        {
            if (i1 == i2) return 0;
            else if (i1 == PriorityNumber) return -1;
            else return 1;
        }
        else return i1.CompareTo(i2);
    };
    private static int IntCompareWithPriority3(int i1, int i2)
    {
        if ((i1 == PriorityNumber) || (i2 == PriorityNumber))
        {
            if (i1 == i2) return 0;
            else if (i1 == PriorityNumber) return -1;
            else return 1;
        }
        else return i1.CompareTo(i2);
    }
}

It seems that I’m not accomplishing much in Example 1. Using lambdas is a little easier to write, since I don’t have to do any casting. However, any of the method local variables that I want to pass into the delegate I can do so through the object state parameter.

In Example 2, it seems much cleaner to use the method local variables, as opposed to setting a static variable, especially since the static variable implementation doesn’t seem it would be thread-safe.

I’m looking for an answer as to the best use of lambda functions and which of the Cases are best optimized in each of the Examples above.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T01:03:38+00:00Added an answer on June 1, 2026 at 1:03 am

    In your first case, the only benefit that you get using lambdas/anonymous methods over a method is that you avoid the casting between object and the type that you want to use; if you are relying heavily on value-types, then you’ll incur boxing every time that method (with a parameter of type object) is called.

    Normally, that’s not a big deal, but if your dealing with really high counts of the callback, it can start having an impact.

    Lambdas (that are not Expression<T>)/anonymous methods and a delegate that points to a method are no different; the C# compiler compiles the lambda/anonymous function into a method on a class that your code doesn’t see and then wires the delegate up to that.

    The MSDN page you link to states (emphasis mine):

    lambda expressions supersede anonymous methods as the preferred way to write inline code

    Because they mention “inline code”, lambdas provide the most succinct way of writing code; since it’s inline, most would naturally want to have the the most brief representation possible. After all, what’s more readable, this:

    var query = myEnumerable.Where(x => x > 2);
    

    Or this?

    var query = myEnumerable.Where(delegate(x) { return x > 2; });
    

    It’s more typing in the second case than in the first for the exact same thing. Additionally, if the method signature that took the delegate ever changed from a delegate to an Expression<T> (presumably, to do some analysis of the lambda for some benefit), then code that calls that with a lambda would still compile, while the code that uses a delegate or anonymous function would not.

    Note, there is also only one method that is generated for the lambda/anonymous delegate. It doesn’t create multiple methods depending on where the variable is declared. What the compiler ends up doing is creating a method with a wider scope.

    Using your (modified) example:

    public static void TestMethod()
    {
        // Scope of the lambda starts here.
    
        for (int i = 1; i <= 12; i++)
        {
            // Case A
            ThreadPool.QueueUserWorkItem((state) => {
                Console.WriteLine(i);
            });
        }
    
        // And ends here.
     }
    

    The method that the compiler creates will close over the loop, so that you might get repeated values for i (depending on when the ThreadPool picks up the call).

    However, when you assign the variable inside the loop, the compiler is smart enough to know it only needs the code inside, like so:

    public static void TestMethod()
    {
        for (int i = 1; i <= 12; i++)
        {
            // Scope of the lambda starts here.  
    
            // Create copy.
            int copy = i;
    
            // Case A
            ThreadPool.QueueUserWorkItem((state) => {
                Console.WriteLine(copy);
            });
    
            // And ends here.
        }
    }
    

    In the above, each callback to the ThreadPool will print out a distinct value.

    It should be noted that in C# 5.0, there is a breaking change to this behavior for the foreach statement, but not the for statement.

    Many developers don’t understand the impact of the closure over the loop, which is the primary reason for the change.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I know this can be done in many ways but im curious as to
While there are multiple ways to reverse bit order in a byte, I'm curious
I am curious: I know there are 2 ways of csrf protection in Django:
I've just started to learn python. I'm curious about what are the efficient ways
I was curious if anyone had insight on what is the best way for
There are a few ways to get class-like behavior in javascript, the most common
I feel curious this morning and was wandering if somebody had a better way
As a SOAP web services developer, I'm curious about what techniques I can implement
Im currently trying out the ajax feature, and im curious about how can i
The C# compiler requires that whenever a custom type defines operator == , it

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.