zoukankan      html  css  js  c++  java
  • C# 中编译器是如何实现闭包的

     首先假设我们有如下的一个扩展方法:      

            public static void LockExec<T>(this T obj, Action<T> action) where T : class
    {
    lock (obj)
    {
    action(obj);
    }
    }

    我们用这个扩展方法写下了如下的代码:

            static void TestInsert(bool canInsert, string insertValue)
    {
    var list1 = new List<string>();
    list1.LockExec(
    (list) =>
    {
    if (canInsert && !list.Contains(insertValue))
    {
    list.Add(insertValue);
    }
    });
    }

    在这个例子中的Lambda表达式中从表面看来只有list是Action<T>传进来的变量,canInsert,insertValue对于Lamba表达式来时都是外部变量,为什么这个表达式还能通过编译且正确运行呢?其实这是c#编译器帮我们做的一个工作,c#编译器将上面的代码编译成下边的代码,编译器为我们生成了一个内部类,来保存Lambda表达式引用的外部变量值,并将这个内部类的实例方法传递给Action<T>,这样这个Action<T>对象的Target和Mothed属性就都有值了,而且这个Action<T>的方法调用将采用实例方法调用,也就是说会有this指针。

        static void TestInsert(bool canInsert, string insertValue)
    {
    var list1 = new List<string>();
    var innerClass = new InnerClass { InnerProperty1 = canInsert, InnerProperty2 = insertValue };
    list1.LockExec(innerClass.InnerMothed);
    }

    internal class InnerClass
    {
    public bool InnerProperty1
    {
    get; set;
    }

    public string InnerProperty2
    {
    get; set;
    }

    public void InnerMothed(List<string> list)
    {
    if (InnerProperty1 && !list.Contains(InnerProperty2))
    {
    list.Add(InnerProperty2);
    }
    }
    }
  • 相关阅读:
    第12组 Beta冲刺 (3/5)
    第12组 Beta冲刺 (2/5)
    第12组 Beta冲刺 (1/5)
    每周小结(1/3)
    第03组 Beta冲刺 (4/5)
    第03组 Beta冲刺 (3/5)
    第03组 Beta冲刺 (1/5)
    第03组 Alpha冲刺 总结
    第03组 Alpha冲刺 (6/6)
    第03组 Alpha冲刺 (4/6)
  • 原文地址:https://www.cnblogs.com/zanxiaofeng/p/1929917.html
Copyright © 2011-2022 走看看