Can I put a return statement inside a lock

后端 未结 3 1508
温柔的废话
温柔的废话 2021-01-01 20:07

Dupe: return statement in a lock procedure: inside or outside

The title is a little misleading. I know that you can do it, but I\'m wondering about

3条回答
  •  灰色年华
    2021-01-01 20:44

    The C# compiler will move the return statement outside of the try/finally that is created for the lock statement. Both of your examples are identical in terms of the IL that the compiler will emit for them.

    Here is a simple example proving that:

    class Example
    {
        static Object obj = new Object();
    
        static int Foo()
        {
            lock (obj)
            {
                Console.WriteLine("Foo");
                return 1;
            }
        }
    
        static int Bar()
        {
            lock (obj)
            {
                Console.WriteLine("Bar");
            }
            return 2;
        }
    }
    

    The code above gets compiled to the following:

    internal class Example
    {
            private static object obj;
    
            static Example()
            {
                    obj = new object();
                    return;
            }
    
            public Example()
            {
                    base..ctor();
                    return;
            }
    
            private static int Bar()
            {
                    int CS$1$0000;
                    object CS$2$0001;
                    Monitor.Enter(CS$2$0001 = obj);
            Label_000E:
                    try
                    {
                            Console.WriteLine("Bar");
                            goto Label_0025;
                    }
                    finally
                    {
                    Label_001D:
                            Monitor.Exit(CS$2$0001);
                    }
            Label_0025:
                    CS$1$0000 = 2;
            Label_002A:
                    return CS$1$0000;
            }
    
            private static int Foo()
            {
                    int CS$1$0000;
                    object CS$2$0001;
                    Monitor.Enter(CS$2$0001 = obj);
            Label_000E:
                    try
                    {
                            Console.WriteLine("Foo");
                            CS$1$0000 = 1;
                            goto Label_0026;
                    }
                    finally
                    {
                    Label_001E:
                            Monitor.Exit(CS$2$0001);
                    }
            Label_0026:
                    return CS$1$0000;
            }
    }
    

    As you can see, the compiler has taken the libery of moving the return statement in Foo outside of the try/finally.

提交回复
热议问题