用MVC5+EF6+WebApi 做一个小功效(三) 项目搭建

 

运作时分支

  这一个形式和自定义型方法有些类似,唯一的不比是它不是在概念自己,而是在概念此外艺术。当然,只有当以此点子基于属性定义的时候才有这种实现的也许。

public Action AutoSave { get; private set; }

public void ReadSettings(Settings settings)
{
    /* Read some settings of the user */

    if(settings.EnableAutoSave)
        AutoSave = () => { /* Perform Auto Save */ };
    else
        AutoSave = () => { }; //Just do nothing!
}

  可能有人会觉得这多少个没什么,不过仔细考虑,你在外界只需要调用AutoSave就足以了,另外的都毫无管。而这么些AutoSave,也不用每一遍执行的时候都亟需去反省部署文件了。

除此以外作为一个机体,还远远没有达成想电脑这样的低耦合度,所以大部分零部件更换的财力都很高。尽管是一台总计机,要更换零件也是要考虑到一体化平台的架构等等音讯,所以谈到低耦合,可替换的时候在不是没法情况下,使用的几率很小。

小功用的分段

 

俺们这多少个小项目分四层,分别为

  • 特朗普(Trump).Domain 紧要存放模型,不引用任何项目
  • 特朗普.EF 实现数量持久化内容,本案中采纳EF6,所以这里会有大量EF
    CRUD实现的操作,依赖Domain项目
  • 特朗普.Application
    实现多少与UI的并行,经过EF处理的数量在这一层转接为DTO重返到UI层,依赖Domain、EF项目
  • Trump.ExamApp UI层实现,使用MVC5+Web
    Api+jQuery+Bootstrap构建,依赖Domain、Application层。

一般项目中还会有一个声援类的品种,提供部分常用方法封装,扩展方法等,并不作为任何项目独有,所以这边就不列出来了。

 

对象即时起初化

  我们知道.NET为我们提供了匿名对象,这使用咱们可以像在JavaScript里面一样随便的始建大家想要对象。不过别忘了,JavaScript里面可以不仅能够放入数据,还足以放入方法,.NET可以么?要相信,Microsoft不会让我们失望的。

//Create anonymous object
var person = new {
    Name = "Jesse",
    Age = 28,
    Ask = (string question) => {
        Console.WriteLine("The answer to `" + question + "` is certainly 42!");
    }
};

//Execute function
person.Ask("Why are you doing this?");

  可是只要您确实是运作这段代码,是会抛出特其余。问题就在那边,兰姆da表达式是不同意赋值给匿名对象的。不过委托可以,所以在此地大家只需要报告编译器,我是一个如何品种的信托即可。

var person = new {
    Name = "Florian",
    Age = 28,
    Ask = (Action<string>)((string question) => {
        Console.WriteLine("The answer to `" + question + "` is certainly 42!");
    })
};

  不过此间还有一个题材,假使本身想在Ask方法里面去做客person的某一个性能,可以么?

var person = new
{
                Name = "Jesse",
                Age = 18,
                Ask = ((Action<string>)((string question) => {
                    Console.WriteLine("The answer to '" + question + "' is certainly 20. My age is " + person.Age );
                }))
};

  结果是连编译都通可是,因为person在大家的拉姆(Lamb)da表明式这里如故不曾定义的,当然不同意行使了,然而在JavaScript里面是从未问题的,如何做呢?.NET能行么?当然行,既然它要超前定义,我们就提前定义好了。

dynamic person = null;
person = new {
    Name = "Jesse",
    Age = 28,
    Ask = (Action<string>)((string question) => {
        Console.WriteLine("The answer to `" + question + "` is certainly 42! My age is " + person.Age + ".");
    })
};

//Execute function
person.Ask("Why are you doing this?");  

项目分层结构也要在此处说一下,这一次这么些小效用仿照DDD的分支形式,一定记住自己说的是模拟。因为自身也不懂DDD,我就画个皮。

用Lambda表明式实现部分在JavaScript中流行的情势

  说到JavaScript,目前些年正是风声水起。不光能够动用拥有我们软件工程现存的一些设计格局,并且由于它的油滑,还有一对出于JavaScript特性而爆发的格局。比如说模块化,顿时实施方法体等。.NET由于是强类型编译型的言语,灵活性自然不如JavaScript,但是这并不意味JavaScript能做的事情.NET就不可以做,下边我们就来落实部分JavaScript中好玩的写法。

 

自定义型方法

  自定义型方法在JavaScript中相比广泛,重要实现思路是其一措施被设置成一个特性。在给这多少个特性附值,甚至推行进程中大家得以每一天变动这一个特性的针对,从而达到改变这些法子的目地。

class SomeClass
{
    public Func<int> NextPrime
    {
        get;
        private set;
    }

    int prime;

    public SomeClass
    {
        NextPrime = () => {
            prime = 2;

            NextPrime = () => {
                   // 这里可以加上 第二次和第二次以后执行NextPrive()的逻辑代码
                return prime;
            };

            return prime;
        }
    }
}

  下面的代码中当NextPrime第一次被调用的时候是2,与此同时,我们转移了NextPrime,我们得以把它指向另外的办法,和JavaScrtip的油滑比起来也不差吧?即便您还不满意,这下边的代码应该能满足你。

Action<int> loopBody = i => {
    if(i == 1000)
        loopBody = //把loopBody指向别的方法

    /* 前10000次执行下面的代码 */
};

for(int j = 0; j < 10000000; j++)
    loopBody(j);

  在调用的地点我们不用考虑太多,然后这一个法子本身就所有调优性了。我们原本的做法或许是在认清i==1000过后平昔写上相应的代码,那么和现在的把该方法指向此外一个办法有怎么样分别呢?

有鉴于此,领域驱动设计的中坚是起家科学的小圈子模型

了解Lambda     

  在.NET
1.0的时候,大家都晓得咱们日常采纳的是寄托。有了寄托呢,大家就可以像传递变量一样的传递形式。在自然程序上来讲,委托是一种强类型的托管的章程指针,曾经也一时被我们用的那叫一个广泛呀,可是总的来说委托行使起来依旧有局部繁琐。来探视使用一个委托一起要以下多少个步骤:

  1. 用delegate关键字创设一个信托,包括声明重临值和参数类型
  2. 运用的地点接到这些委托
  3. 成立那个委托的实例并点名一个再次来到值和参数类型匹配的形式传递过去

  复杂呢?可以吗,也许06年你说不复杂,不过现在,真的挺复杂的。

  后来,幸运的是.NET
2.0为了们带来了泛型。于是大家有了泛型类,泛型方法,更关键的是泛型委托。最终在.NET3.5的时候,大家Microsoft的哥们儿们毕竟意识到骨子里大家只需要2个泛型委托(使用了重载)就可以覆盖99%的接纳情形了。

  • Action 没有输入参数和再次来到值的泛型委托
  • Action<T1, …, T16> 可以吸纳1个到16个参数的无重临值泛型委托
  • Func<T1, …, T16, 陶特>
    可以接收0到16个参数并且有重回值的泛型委托

  这样大家就可以跳过地点的首先步了,但是第2步仍然必须的,只是用Action或者Func替换了。别忘了在.NET2.0的时候大家还有匿名形式,虽然它没怎么流行起来,然而大家也给它
一个成名的时机。

Func<double, double> square = delegate (double x) {
    return x * x;
}

  最终,终于轮到我们的兰姆(Lamb)da优雅的上场了。

// 编译器不知道后面到底是什么玩意,所以我们这里不能用var关键字
Action dummyLambda = () => { Console.WriteLine("Hello World from a Lambda expression!"); };

// double y = square(25);
Func<double, double> square = x => x * x;

// double z = product(9, 5);
Func<double, double, double> product = (x, y) => x * y;

// printProduct(9, 5);
Action<double, double> printProduct = (x, y) => { Console.WriteLine(x * y); };

// var sum = dotProduct(new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 });
Func<double[], double[], double> dotProduct = (x, y) =>
{
    var dim = Math.Min(x.Length, y.Length);
    var sum = 0.0;
    for (var i = 0; i != dim; i++)
        sum += x[i] + y[i];
    return sum;
};

// var result = matrixVectorProductAsync(...);
Func<double, double, Task<double>> matrixVectorProductAsync = async (x, y) =>
{
    var sum = 0.0;
    /* do some stuff using await ... */
    return sum;
};

 

  从地方的代码中大家可以看来:

  • 假若唯有一个参数,不需要写()
  • 设若唯有一条实施语句,并且我们要回来它,就不需要{},并且永不写return
  • 兰姆(Lamb)da可以异步执行,只要在面前加上async关键字即可
  • Var关键字在大部分场合下都不可能应用

  当然,关于最后一条,以下这多少个境况下大家仍可以够用var关键字的。原因很简短,我们报告编译器,后边是个什么样品种就可以了。

Func<double,double> square = (double x) => x * x;

Func<string,int> stringLengthSquare = (string s) => s.Length * s.Length;

Action<decimal,string> squareAndOutput = (decimal x, string s) =>
{
    var sqz = x * x;
    Console.WriteLine("Information by {0}: the square of {1} is {2}.", s, x, sqz);
};

  现在,我们早就清楚Lambda的局部着力用法了,尽管单纯就那么些事物,这就不叫快乐的Lambda表明式了,让大家看看下面的代码。

var a = 5;
Func<int,int> multiplyWith = x => x * a;
var result1 = multiplyWith(10); //50
a = 10;
var result2 = multiplyWith(10); //100

  是不是有好几觉得了?我们得以在拉姆(Lamb)da表明式中用到外边的变量,没错,也就是风传中的闭包啦。

void DoSomeStuff()
{
    var coeff = 10;
    Func<int,int> compute = x => coeff * x;
    Action modifier = () =>
    {
        coeff = 5;
    };

    var result1 = DoMoreStuff(compute);

    ModifyStuff(modifier);

    var result2 = DoMoreStuff(compute);
}

int DoMoreStuff(Func<int,int> computer)
{
    return computer(5);
}

void ModifyStuff(Action modifier)
{
    modifier();
}

  在上头的代码中,DoSomeStuff方法里面的变量coeff实际是由外部方法ModifyStuff修改的,也就是说ModifyStuff这么些方法拥有了走访DoSomeStuff里面一个部分变量的力量。它是什么成功的?我们顿时会说的J。当然,这些变量功能域的题目也是在动用闭包时应有专注的地点,稍有不慎就有可能会吸引你不意的结果。看看上面这多少个您就通晓了。

var buttons = new Button[10];

for (var i = 0; i < buttons.Length; i++)
{
    var button = new Button();
    button.Text = (i + 1) + ". Button - Click for Index!";
    button.OnClick += (s, e) => { Messagebox.Show(i.ToString()); };
    buttons[i] = button;
}

  猜猜你点击这多少个按钮的结果是什么?是”1, 2,
3…”。可是,其实真正的结果是任何都显示10。为啥?不明觉历了吗?那么一旦避免这种情况吗?

var button = new Button();
var index = i;
button.Text = (i + 1) + ". Button - Click for Index!";
button.OnClick += (s, e) => { Messagebox.Show(index.ToString()); };
buttons[i] = button;

  其实做法很简单,就是在for的循环之中把当前的i保存下来,那么每一个表达式里面储存的值就不平等了。

  接下去,我们整点高级的货,和兰姆da息息相关的表明式(Expression)。为何说怎么有关,因为大家得以用一个Expression将一个兰姆da保存起来。并且同意大家在运行时去解释这几个拉姆(Lamb)da表明式。来看一下底下简单的代码:

Expression<Func<MyModel, int>> expr = model => model.MyProperty;
var member = expr.Body as MemberExpression;
var propertyName = member.Expression.Member.Name; 

  这么些确实是Expression最简便的用法之一,我们用expr存储了后头的表明式。编译器会为大家转移表明式树,在表达式树中包括了一个元数据像参数的项目,名称还有方法体等等。在LINQ
TO
SQL中就是经过这种办法将大家设置的标准经过where扩充方法传递给末端的LINQ
Provider举行解释的,而LINQ
Provider解释的历程实际上就是将表达式树转换成SQL语句的长河。

譬如说我们这个序列,就是一个小的效率,现在可预估的用户量就是您自己她,你非要在还没上线没成型就考虑百万级用户的扩张,揣测这一个系列永远都没法上线了。

图片 1

松开项目上的一个例证,比如引入工作单元、仓储层的概念,就是为了隔离领域与数码持久化,不过真正项目上线,要替换数据持久化的那一层谈何容易。基于项目现有应用场景,然后开展技能选型的时候,要综合支出功效,开发成本,可扩大性,可维护性等等,并不是哪些惊天动地上就用哪些,什么概念都要涉及,这样只会成为一场技术点堆砌而难以实际运用。

自举办办法

  JavaScript 中的自实施模式有以下多少个优势:

  1. 不会传染全局环境
  2. 确保自实施里面的措施只会被执行几遍
  3. 演讲完立时实施

  在C#中我们也可以有自推行的方法:

(() => {
    // Do Something here!
})();

  上边的是平昔不参数的,假诺您想要参与参数,也不行的简约:

((string s, int no) => {
    // Do Something here!
})("Example", 8);

  .NET4.5最闪的新效能是怎么?async?那里也得以

await (async (string s, int no) => {
    // 用Task异步执行这里的代码
})("Example", 8);

// 异步Task执行完之后的代码  

技术尚未好坏,唯有切合不吻合!当然,php是最好的语言,这是江湖真理!

重返方法

  我们在JavaScript中得以间接return一个办法,在.net中虽然无法直接再次回到方法,但是我们得以回来一个表明式。

Func<string, string> SayMyName(string language)
{
    switch(language.ToLower())
    {
        case "fr":
            return name => {
                return "Je m'appelle " + name + ".";
            };
        case "de":
            return name => {
                return "Mein Name ist " + name + ".";
            };
        default:
            return name => {
                return "My name is " + name + ".";
            };
    }
}

void Main()
{
    var lang = "de";
    //Get language - e.g. by current OS settings
    var smn = SayMyName(lang);
    var name = Console.ReadLine();
    var sentence = smn(name);
    Console.WriteLine(sentence);
}

  是不是有一种政策格局的感到?这还不够完善,这一堆的switch
case看着就心烦,让大家用Dictionary<TKey,电视alue>来简化它。来探望来面这货:

static class Translations
{
    static readonly Dictionary<string, Func<string, string>> smnFunctions = new Dictionary<string, Func<string, string>>();

    static Translations()
    {
        smnFunctions.Add("fr", name => "Je m'appelle " + name + ".");
        smnFunctions.Add("de", name => "Mein Name ist " + name + ".");
        smnFunctions.Add("en", name => "My name is " + name + ".");
    }

    public static Func<string, string> GetSayMyName(string language)
    {
        //Check if the language is available has been omitted on purpose
        return smnFunctions[language];
    }
}

开创解决方案及创制项目(Vs 2017)

来吧来啊,新建空白解决方案,然后添加MVC项目,名字叫特朗普(Trump).ExamApp,这么些很基础很基础的,只列一下留意点

1.精选ASP.NET Web应用程序.NET Framework
,下边分外是传说中的跨平台版本。相比落后,看了五遍视频都是第几集。

图片 2

2.增选MVC,同时勾选Web
API(不勾选亦可以,可以由此Nuget添加),身份验证这里采取不举办身份验证。()

图片 3

 

身份验证:

不开展身份验证:不选择net自带的地位管理

个人用户账号:集成Asp.Net Identity v2(.NET Framework) or v3+(.NET
Core)版本

图片 4

3.开立完毕后如图

图片 5

4.拔取Nuget管理项目中的引用

在项目上右键,管理Nuget程序包,移除“Microsoft.ApplicationInsights”。Application
Insights 是可扩展的应用程序性能管理 (APM) 服务,可让 Web
开发人员在多少个阳台上转移和管理应用。暂时用不到,但是package有少数个,习惯性移除掉,然后就是升格一下除了jQuery外所有的包。

注意:因为兼容性问题,jQuery版本不要随便更改

图片 6

 

好了。到此为止,这一个项目基本截至,接下去就是按照约定的名字创办其他多少个门类,选拔项目为类库(.NET
Framework)。

 

都成立完毕后,刷新一下,然后生成解决方案。把Web项目设置为启动项目,F5起步调试,大家任何项目标官气基本搭建完毕。

快乐的Lambda表达式(二)

以一种领域专家、设计人士、开发人士都能了然的通用语言作为互相交换的工具,在交换的长河中发觉世界概念,然后将这多少个概念设计成一个世界模型;
由世界模型驱动软件设计,用代码来贯彻该领域模型;

总结

  兰姆da表达式在最后编译之后实质是一个模式,而大家表明兰姆(Lamb)da表明式呢实质上是以信托的款型传递的。当然我们还足以由此泛型表达式Expression来传递。通过Lambda表明式形成闭包,可以做过多事情,但是有一部分用法现在还设有争议,本文只是做一个概述
:),假使有不妥,还请拍砖。谢谢辅助 🙂

再有更多兰姆(Lamb)da表明式的不同平日玩法,请移步: 私自的故事之 –
快乐的拉姆(Lamb)da表明式(二)

 原文链接: http://www.codeproject.com/Articles/507985/Way-to-Lambda

领域驱动设计的经典分层架构

图片 7

  本文会介绍到一些兰姆da的基础知识,然后会有一个微细的特性测试对照Lambda表明式和一般方法的属性,接着我们会透过IL来深刻摸底兰姆(Lamb)da到底是何许,最终大家将用Lambda表明式来实现部分JavaScript里面相比较广泛的形式。

DDD这一个事物粤语名字应该叫天地驱动设计,园子很多大神分享过、讲解过。看了成百上千博客很多书,仍旧没太了解这么复杂的东西(没有履行,纸上得来终觉浅)。这里大概说说自己的知道,把事情逻辑尽量的会聚在领域层(Domain),假使项目是人体,这世界层就是人身的大脑了,以明天的科技,身上的零部件除了大脑基本都可替换。也许可以把大脑换来另一个人身上,不过,整个身子依旧要听大脑的指挥。如若人体尚未了大脑,基本上就是一滩肉,失去了作为机体的效益。

  自从兰姆da随.NET
Framework3.5涌出在.NET开发者面前的话,它已经给我们带来了太多的欣喜。它优雅,对开发者更团结,能增长支付功用,天啊!它还有可能下滑暴发一些私房错误的或许。LINQ包括ASP.NET
MVC中的很多功用都是用兰姆(Lamb)da实现的。我不得不说自从用了兰姆da,我腰也不酸了,腿也不疼了,手指也不抽筋了,就连写代码bug都少了。小伙伴们,你们后日用Lambda了么?但是你真的领悟它么?明日我们就来出彩的认识一下呢。

要详细摸底DDD的概念可以打开下面的链接,包括下方图片,也是从著作中粘过来的,在此我们只是用她的分段,并从未履行DDD。

回调形式

  回调情势也并非JavaScript特有,其实在.NET1.0的时候,我们就可以用委托来促成回调了。然则明天大家要实现的回调可就不相同了。

void CreateTextBox()
{
    var tb = new TextBox();
    tb.IsReadOnly = true;
    tb.Text = "Please wait ...";
    DoSomeStuff(() => {
        tb.Text = string.Empty;
        tb.IsReadOnly = false;
    });
}

void DoSomeStuff(Action callback)
{
    // Do some stuff - asynchronous would be helpful ...
    callback();
}

  上边的代码中,大家在DoSomeStuff完成之后,再做一些工作。这种写法在JavaScript中是很宽泛的,jQuery中的Ajax的oncompleted,
onsuccess不就是那样实现的么?又或者LINQ扩张方法中的foreach不也是这么的么?

一般一个档次始于此前都会有启动会,需求交底等等,其中会有一个环节,大讲特讲项目标意义,然后取一个宏伟上的门类名字,咱这是一个小效率谈不上体系,不过名字无法太抠门了。好呢,就叫特朗普(Trump)吧。没有此外意义,玩嘛!

Lambda表达式的性质

  关于Lambda性能的题目,我们率先可能会问它是比平时的不二法门快吧?还是慢呢?接下去我们就来一钻探竟。首先大家通过一段代码来测试一下见怪不怪方法和Lambda表达式之间的性质差别。

class StandardBenchmark : Benchmark
{
    const int LENGTH = 100000;
    static double[] A;
    static double[] B;

    static void Init()
    {
        var r = new Random();
        A = new double[LENGTH];
        B = new double[LENGTH];

        for (var i = 0; i < LENGTH; i++)
        {
            A[i] = r.NextDouble();
            B[i] = r.NextDouble();
        }
    }

    static long LambdaBenchmark()
    {
        Func<double> Perform = () =>
        {
            var sum = 0.0;

            for (var i = 0; i < LENGTH; i++)
                sum += A[i] * B[i];

            return sum;
        };
        var iterations = new double[100];
        var timing = new Stopwatch();
        timing.Start();

        for (var j = 0; j < iterations.Length; j++)
            iterations[j] = Perform();

        timing.Stop();
        Console.WriteLine("Time for Lambda-Benchmark: \t {0}ms", timing.ElapsedMilliseconds);
        return timing.ElapsedMilliseconds;
    }

    static long NormalBenchmark()
    {
        var iterations = new double[100];
        var timing = new Stopwatch();
        timing.Start();

        for (var j = 0; j < iterations.Length; j++)
            iterations[j] = NormalPerform();

        timing.Stop();
        Console.WriteLine("Time for Normal-Benchmark: \t {0}ms", timing.ElapsedMilliseconds);
        return timing.ElapsedMilliseconds;
    }

    static double NormalPerform()
    {
        var sum = 0.0;

        for (var i = 0; i < LENGTH; i++)
            sum += A[i] * B[i];

        return sum;
    }
}
}

  代码很粗略,我们透过履行同样的代码来相比,一个位于Lambda表达式里,一个坐落平时的艺术里面。通过4次测试得到如下结果:

  Lambda  Normal-Method

  70ms  84ms
  73ms  69ms
  92ms  71ms
  87ms  74ms

  按理来说,兰姆da应该是要比常见方法慢很小一点点的,不过不晓得第一次的时候怎么Lambda会比一般方法还快一些。-
-!不过经过如此的对照自己想至少可以表达Lambda和平日方法之间的特性其实几乎是从未区分的。  

  那么Lambda在通过编译之后会变成什么样体统呢?让LINQPad告诉你。

图片 8

  上图中的兰姆(Lamb)da说明式是如此的:

Action<string> DoSomethingLambda = (s) =>
{
    Console.WriteLine(s);// + local
};

  对应的无独有偶方法的写法是这样的:

void DoSomethingNormal(string s)
{
    Console.WriteLine(s);
}

  上边两段代码生成的IL代码呢?是如此地:

DoSomethingNormal:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  call        System.Console.WriteLine
IL_0007:  nop         
IL_0008:  ret         
<Main>b__0:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  call        System.Console.WriteLine
IL_0007:  nop         
IL_0008:  ret       

  最大的不等就是艺术的名目以及艺术的施用而不是声称,申明实际上是千篇一律的。通过下边的IL代码我们可以看到,那个表明式实际被编译器取了一个称呼,同样被放在了近年来的类里面。所以实际,和我们调类里面的不二法门没有什么样两样。下边这张图表明了这个编译的经过:

图片 9

  下边的代码中尚无使用外部变量,接下去大家来看此外一个事例。

void Main()
{
    int local = 5;

    Action<string> DoSomethingLambda = (s) => {
        Console.WriteLine(s + local);
    };

    global = local;

    DoSomethingLambda("Test 1");
    DoSomethingNormal("Test 2");
}

int global;

void DoSomethingNormal(string s)
{
    Console.WriteLine(s + global);
}

  本次的IL代码会有什么样不同么?

IL_0000:  newobj      UserQuery+<>c__DisplayClass1..ctor
IL_0005:  stloc.1     
IL_0006:  nop         
IL_0007:  ldloc.1     
IL_0008:  ldc.i4.5    
IL_0009:  stfld       UserQuery+<>c__DisplayClass1.local
IL_000E:  ldloc.1     
IL_000F:  ldftn       UserQuery+<>c__DisplayClass1.<Main>b__0
IL_0015:  newobj      System.Action<System.String>..ctor
IL_001A:  stloc.0     
IL_001B:  ldarg.0     
IL_001C:  ldloc.1     
IL_001D:  ldfld       UserQuery+<>c__DisplayClass1.local
IL_0022:  stfld       UserQuery.global
IL_0027:  ldloc.0     
IL_0028:  ldstr       "Test 1"
IL_002D:  callvirt    System.Action<System.String>.Invoke
IL_0032:  nop         
IL_0033:  ldarg.0     
IL_0034:  ldstr       "Test 2"
IL_0039:  call        UserQuery.DoSomethingNormal
IL_003E:  nop         

DoSomethingNormal:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  ldarg.0     
IL_0003:  ldfld       UserQuery.global
IL_0008:  box         System.Int32
IL_000D:  call        System.String.Concat
IL_0012:  call        System.Console.WriteLine
IL_0017:  nop         
IL_0018:  ret         

<>c__DisplayClass1.<Main>b__0:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  ldarg.0     
IL_0003:  ldfld       UserQuery+<>c__DisplayClass1.local
IL_0008:  box         System.Int32
IL_000D:  call        System.String.Concat
IL_0012:  call        System.Console.WriteLine
IL_0017:  nop         
IL_0018:  ret         

<>c__DisplayClass1..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret      

  你意识了吧?六个方法所编译出来的情节是一律的,
DoSomtingNormal和<>c__DisplayClass1.<Main>b__0,它们之中的内容是千篇一律的。可是最大的不平等,请小心了。当大家的Lambda表明式里面用到了表面变量的时候,编译器会为这么些兰姆(Lamb)da生成一个类,在这些类中蕴含了大家表达式方法。在应用这些兰姆da表明式的地点呢,实际上是new了那个类的一个实例举办调用。那样的话,我们表明式里面的表面变量,也就是下边代码中用到的local实际上是以一个全局变量的身价存在于那些实例中的。

图片 10

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图