05
8

从WebForm到MVC,一直到Blazor

0
归档:2021年8月分类:C#和.NET

打算下一个项目用Blazor,学习了一个下午,这是一个很不错的全栈UI框架,基于WebAssembly技术,可以让开发人员直接用C#完成js的工作。

学习过程中,我脑子里闪现了自己经历的那个ASP.NET的WebForm时代,那时候我们用UserControl的ascx文件布局网页。查了下,果然是一脉相承。
https://docs.microsoft.com/en-us/dotnet/architecture/blazor-for-web-forms-developers/architecture-comparison

我把消息发群里,大家开始回忆曾经用过的方法,包括ViewState,GridView,IsPostBack,masterpage,repeater,这些技术确实都是一代人的回忆。

不过认真回想,微软的WwebFrom的理念是超前的, 只不过碍于当时的技术发展, 只能做成那样,后来的UI框架其实都给予它的思想。

“技术会落后,思想传承”,微软的技术从WebForm到MVC,一直到一直到Blazor,使用的WebUI的组件技术一直都没有改变,果然是汇集世界一流软件工程师的公司。

21
7

[转]龙应台的《(不)相信》

0
归档:2021年7月分类:点滴生活

二十岁之前相信的很多东西,后来一件一件变成不相信。

曾经相信过爱国,后来知道“国”的定义有问题,通常那谆谆善诱要你爱国的人所定义的“国”,不一定可爱,不一定值得爱,而且更可能值得推翻。

曾经相信过历史,后来知道,原来历史的一半是编造。前朝史永远是后朝人在写,后朝人永远在否定前朝,他的后朝又来否定他,但是负负不一定得正,只是累积渐进的扭曲变形移位,使真相永远掩盖,无法复原。说“不容青史尽成灰”,表达的正是,不错,青史往往是要成灰的。指鹿为马,也往往是可以得逞和胜利的。

曾经相信过文明的力量,后来知道,原来人的愚昧和野蛮不因文明的进展而消失,只是愚昧野蛮有很多不同的面貌:纯朴的农民工人、深沉的知识分子、自信的政治领袖、替天行道的王师,都可能有不同形式的巨大愚昧和巨大野蛮,而且野蛮和文明之间,竟然只有极其细微、随时可以被抹掉的一线之隔。

曾经相信过正义,后来知道,原来同时完全可以存在两种正义,而且彼此抵触,冰火不容。选择其中之一,正义同时就意味着不正义。而且,你绝对看不出,某些人在某一个特定的时机热烈主张某一个特定的正义,其中隐藏着深不可测的不正义。

曾经相信过理想主义者,后来知道,理想主义者往往经不起权力的测试:一掌有权力,他或者变成当初自己誓死反对的“邪恶”,或者,他在现实的场域不堪一击,一下就被弄权者拉下马来,完全没有机会去实现他的理想。理想主义者要有品格,才能不被权力腐化;理想主义者要有能力,才能将理想转化为实践。可是理想主义者兼具品格及能力者,几希。

曾经相信过爱情,后来知道,原来爱情必须转化为亲情才可能持久,但是转化为亲情的爱情,犹如化入杯水中的冰块——它还是冰块吗?

曾经相信过海枯石烂作为永恒不灭的表征,后来知道,原来海其实很容易枯,石,原来很容易烂。雨水,很可能不再来,沧海,不会再成桑田。原来,自己脚下所踩的地球,很容易被毁灭。海枯石烂的永恒,原来不存在。

二十岁之前相信的很多东西,有些其实到今天也还相信。

譬如国也许不可爱,但是土地和人可以爱。譬如史也许不能信,但是对于真相的追求可以无止尽。譬如文明也许脆弱不堪,但是除文明外我们其实别无依靠。譬如正义也许极为可疑,但是在乎正义比不在乎要安全。譬如理想主义者也许成就不了大事大业,但是没有他们社会一定不一样。譬如爱情总是幻灭的多,但是萤火虫在夜里发光从来就不是为了保持光。譬如海枯石烂的永恒也许不存在,但是如果一粒沙里有一个无穷的宇宙,一刹那里想必也有一个不变不移的时间。

那么,有没有什么,是我二十岁前不相信的,现在却信了呢?

有的,不过都是些最平凡的老生常谈。曾经不相信“性格决定命运”,现在相信了。曾经不相信“色即是空”,现在相信了。曾经不相信“船到桥头自然直”,现在有点信了。曾经不相信无法实证的事情,现在也还没准备相信,但是,有些无关实证的感觉,我明白了,譬如李叔同圆寂前最后的手书:“君子之交,其淡如水,执象而求,咫尺千里。问余何适,廓尔忘言,华枝春满,天心月圆。”

相信与不相信之间,彷佛还有令人沉吟的深度。

05
7

关于传染病的数学模型,在许多年前数学界早已做过研究,根据传染病的传播速度不同,空间范围各异,传播途径多样,动力学机理等各种因素,对传染病模型按照传染病的类型划分为 SI,SIR,SIRS,SEIR 模型。如果是按照连续时间来划分,那么这些模型基本上可以划分为常微分方程(Ordinary Differential Equation),偏微分方程(Partial Differential Equation)等多种方程模型;如果是基于离散的时间来划分,那么就是所谓的差分方程(Difference Equation)。差分模型其实是微分模型的离散形式,所以我们只讨论微风方程模型。

首先要介绍一些常用的符号:在时间戳 上,可以定义以下几种人群:

•易感者(susceptible):用符号file 来表示;

•感染者(infective):用符号file来表示;

•康复者(Recoverd):用符号file来表示;

其次,在时间戳t上,总人口是file 。如果暂时不考虑人口增加和死亡的情况,那么N(t)是一个恒定的常数值。

除此之外,

•r表示在单位时间内感染者接触到的易感者人数;

•传染率file:表示感染者接触到易感者之后,易感者得病的概率;

•康复率file:表示感染者康复的概率,有可能变成易感者(可再感染),也有可能变成康复者(不再感染)。

在进行下面的分析之前,先讲一个常微分方程的解。

file

一、SI 模型(Susceptible-Infective Model)

在 SI 模型里面,只考虑了易感者和感染者,并且感染者不能够恢复,此类病症有 HIV 等,模型如下:

file

其微分方程就是:

file

这个微风方程近似解法如下:

file

通过数值模拟的结果:

file

在SI模型的假设下,全部人群到最后都会被感染。

二、SIS模型(Susceptible-Infectious-Susceptible Model)

除了HIV这种比较严重的病之外,还有很多小病可以恢复并且反复感染,例如日常的感冒,发烧等。在这种情况下,感染者就有一定的几率重新转化成易感者。如下图所示:

file

其微分方程是:

file

初始值:filefile

这个方程的数值近似解:

file

三、SIR 模型(Susceptible-Infectious-Recovered Model)

很多时候,感染者在康复了之后就有抗体,于是后续就不再会获得此类病症,这种时候就需要考虑SIR模型。此类病症有麻疹,腮腺炎,风疹等。我们熟悉的SIR模型是基于疫情流行区域的总人数、感染人数、易感人数、病愈人数和时间之间的如下关系:

file

其微分方程是:

file

这些方程里的参数和为常数,反映了特定疫情的特征。这些方程貌似简单,但由于常数和是同一数量级,导致方程属于高度耦合的非线性类型,实际上无法求解析解,需要用数值解来提供预测结果。在疫情扩散过程中的早期,由于开始时易感人群也就是总人数,即 ≈ ,我们可以简化感染人数和时间的关系为:

file

由此可得到感染人数的近似解为:

file

这一关系表明,近似的感染人数总数是时间的指数函数。这里的常数和应该根据疫情的特点来确定,从而实现感染人数的估计。当然,疫情防控措施也会影响这些参数,反过来也反映了防控措施的效果。这些参数一般是根据流行病学的统计结果得到的,会在疫情的流行过程中得到反映。也就是说,我们也可以根据实际疫情报告来决定这些参数。由于我们已经积累了一些疫情实际数据,基于SIR分析的回溯拟合可以精确地确定这些参数。

SIR模型的一些近似结果(预测新冠病毒的有症状的确诊病例):

file

四、总结

最后,除了以上的 SI,SIS,SIR 模型中,还考虑进去。除此之外,如果把潜伏期、潜伏期的传染情况也加进去考虑,还有SIRS模型,SEIR模型等,但是不管怎么变化都是基于SIR这个微分模型,而且有时候考虑的参数越多不一定越准确,比较本身参数就不是绝对精确。

02
7

伯林和自由主义(二)

0
归档:2021年7月分类:政治哲学

这段时间阅读伯林的《自由论》及相关书籍,发现伯林的思想广博又深邃,他是哈耶克和波普尔的好友,他的很多想法甚至超越了穆勒,我特别欣赏他坚持在自由的前提下,坚守多元和容忍。伯林有两篇重要的文章,重要得我不得不转到这里来,为此我专门进行了OCR识别,并且人工校对。

这是第二篇文章,这篇文章可以大致了解伯林对于“自由”的基本论述,这两天在youtube上看到Manufacturing Intellect节目里对伯林的采访,他说了这么一句很令我深思的话:伟大的哲学家的基本理念和思想是非常简单又深刻的,并且他可以通俗地告诉大众,至于他自己的长篇大论,只是在论述、校验和证明自己的思想是经得起推敲的,并且也是对普通人或者其他哲学家的一些想法的反驳。


自由

什么是政治自由?在古代世界,特別在希腊人当中,“是自由的”就是能够参与自己城邦的管理。只冇当一个人冇权参与法律的制定与废除时,法律才是有效的。自由并不是被迫服从别人为他制定的法律,而是服从由他制定的法律。这种民主制使得政府与法律渗透生活的所冇领域成为可能。人不能免于这样的管理,他也不要求免于这样的管理。所有民主主义者都声称,人人都同样可能接受批评、调査、依法传讯(若必需)或其他安排,在建立与维持这些安排时,每个公民都有权参与。

在现代世界,一种新观念产生了一本杰明•贡斯当对之作了最清晰的阐释一这就是:存在着一个私人生活的领域,除了特殊情况外,这个领域朵不希望受公共权力干涉的。古代世界的核心问题是“谁应该统治我?”。有些人说是封主,有些人说是最贤明者,或最富冇者、敁勇敢者、多数派、法院、所有人的匿名表决。在现代世界,一个同等重耍的问题楚:政府应该在多大程度上进行管理?古代世界假定生活是一个整体,法律与政府覆盖其整个领域——没有任何理由保护生活的任何一个角落不受这种监管。在现代世界,历史地说,不管是作为教会反对世俗国家干涉的斗争或国家反对教会的斗争的结果,还始作为私人企业工业、商业的成长及其反对国家干涉的要求的结果,或者还因为别的什么原因,我们开始提出这样的假设在公共生活与私人生活之间存在着界线;无论在这个界线之内我可以依意愿行事,亦即按我軎欢的方式生活、相信我愿意相信之物的私人空间多么狭小,只要我的行为不干涉别人相似的权利,或不损害使这种安排成为吋能的秩序。这是古典自由主义观点,在英国与法同各种各样的人权宣言中,在诸如洛克、伏尔泰、托马斯•潘恩、贡斯巧和约翰•斯图亚特•穆勒等人的著作中,得到完整或部分的表达。当我们说到公民自由(权)或公民价值时,这就是其中的含义之一。

人需要彼此防范和防范政府,这种假设从未在世界的任何地方被完全接受过,我所说的古希腊或古典的观点以这种形式重新出现你说个人有权选择他喜爱的生活。但是这适用于所有人吗?如果这个个体无知、不成熟、未受教育、智力残缺,拒绝恰当的健康与发展机会,他将不可能知道如何选择。这种人从不会真正知道他的真正需要是什么。如果存在这样一些人,他们知道人的本性是什么、人究竟渴望什么,如果他们替其他人做了他们如果更明智、更知情、更成熟、更发达也会做的事情——也许用一些控制的手段——那么,他们是在剥夺后者的自由吗?他们的确干涉了人们,但只是为了让他们能够做如果他们知道得更多也会做的亊悄,或者为了使他们总是处于最佳状态,而非老是受制于非理性的动机或幼稚的举动,或让他们本性中动物的一面占优势。那么这还是干涉吗?如果父母或老师强迫不情愿的孩子上学或努力学习,以虽然孩子们可能并不知道的真实要求为名,那么,既然这是所有真正的人——因为他们是人——都必然要求的,他们还是在剥夺孩子们的自由吗?肯定不是。老师或父母给了他们潜伏的或真实的自我,迎合他们的需要,以反对他们更肤浅的自我暂时的需耍,这些需要在人成熟时就像老皮一样会蜕掉。”

如來你用教会、政党或阀家来代替父母,你就会得到作为许多现代权威之基础的那种理论。我们被告知说,服从这些机构就是服从自己,因此不是受奴役,因为这些机构本身体现着我们最好与最明智的方面,而自我约束并非约束,自我控制并非受奴役。

这两种观点(在其各种版本中)的战斗,乃是现代世界基本的政治议题。一方说把酒瓶放到嗜酒症患者拿不着的地方并未剥夺他的自由;如果他被阻止酗酒,即使是通过强迫,他也会健康起来,能更好地履行他作为人和公民的责任并会更好地成为他自己,这样要比他能够着酒瓶、毁坏他的健康与健全时更自由。他不知道这一点的事实正是他的疾病或他对自己真实需要无知的表现。另一方并不否认有必要对反社会的行为加以抑制,不否认有必要防止他伤害他自己或伤害他自己的孩子或其他人的福利,但是否认这种抑制——虽然是公正的——构成自由。为了让别的利益,如安全、和平或健康有足够的空间,自由也许不得不被剥夺;或者为了明天更大的自由今天的自由不得不被剥夺;但是剥夺自由并不是提供自由,而且,强制,不管有多么好的理由,毕竟是强制而非自由。自由,这些人会说,仅是诸多价值中的一种,如果它构成实现其他同等重要的目标的障碍,或者妨碍其他人实现这些目标的机会,它就必须让路。

对此,另一方的回应是,这种说法预先假定私人生活与公共生活的分裂(它假定人有可能在其私人生活中做一些别人不喜欢的事情,因此需要受到保护),但是这样一种人性观是建立在一种根本的错误之上。人类是一个整体,在一个理想的社会里,当每个人的功能发挥出来时,没有人会想去做那些令别人反感或想阻止的事情。改革家与革命者的恰当的意图,便是去打通人与人之间的高墙,把一切带到开放之境,使人没有分裂地生活在一起,以致一人所欲即万人所欲。要求不被打扰,要求能够做自己愿意做的事而不需要向某个法庭——家庭、雇主、党、政府或整个社会——作解释,这种要求本身便是失调的表现。向社会索要自由就是向自我索要自由。这种病症必须通过改变财产关系(如社会主义要求做的那样),或通过消除批判理性(如一些宗教派别,以及法西斯和其他极权主义政权事实上试图做的那样)予以治疗。

在可以称作有机论的第一种观点中,所有分离都是坏的,不容践踏的人权观念乃是壁垒观念——是人与人之间相互隔离时才需要的墙壁——只有在一个坏的社会里才为人们所需,而在一个组织良好、所有人类小溪都流入统一的人类江河的社会里则没有存在的余地。在第二种或自由主义的观点中,人权,以及私人领域(在其中我不受审查)的观念,对于人人需要的最低限度的自主——如果他要按自己的路线发展的话——是不可缺少的;因为多样性是人类的类本质,而不是行将逝去的状态。这个观点的拥护者认为,毁灭这种权利以建立一种普遍的、自我导向的人类社会——一个所有人向着同一目标进军的社会——将摧毁个人选择的领域;而这一领域,不管多么狭窄,一旦失去,生命亦不再有价值

极权与威权制度以一种粗糙的和(有人会坚持说)扭曲的形式,代表着这些观点的前一种,而自由民主制度倾向于代表后一种。当然,这些观点的变种与联结,以及它们间的妥协,也是可能的。它们是两种基本的、彼此对立的观念,主导着自文艺复兴以来的世界。

01
7

伯林和自由主义(一)

0
归档:2021年7月分类:政治哲学

这段时间阅读伯林的《自由论》及相关书籍,发现伯林的思想广博又深邃,他是哈耶克和波普尔的好友,他的很多想法甚至超越了穆勒,我特别欣赏他坚持在自由的前提下,坚守多元和容忍。伯林有两篇重要的文章,重要得我不得不转到这里来,为此我专门进行了OCR识别,并且人工校对。

第一篇文章是他总结自己的思想史,回顾最重要的两个观点:一是否定历史必然性,即否定决定论,二是再次阐述自己关于消极自由和积极自由的观点。这篇文章摘自伯林的作品《我的思想之路》(1987),全文收录于《观念的力量》(伦敦,2000:温多斯;普林斯顿,2000:普林斯顿大学出版社)。


决定论

政治自由是我在二十世纪五十年代两个讲演的主题。第一个讲演题目是《历史必然性》。在这里,我陈述的观点是:决定论是一种千百年来为无数哲学家广为接受的学说。决定论宣称每个事件都有一个原因,从这个原因中,事件不可避免地产生。这是自然科学的基础:自然规律及这些规律的运用——构成整个自然科学——建立在自然科学所探讨的永恒秩序的观念之上。但是,如果自然的其余部分都是服从于这些规律的,那么唯有人类不服从它们吗?当一个人就像绝大多数平常人(虽然并非绝大多数科学家与哲学家)那样假定,当他从椅子上站起来时他并不是非要这么做不可;他从椅子上起来,是因为他选择这样做,但他并不是必须要做这样的选择——当他这样假定时,他就被告知:这是一种幻觉;随着心理学家的必要工作的完成(它尚未完成,但至少从原则上讲是可以完成的),总有一天他会发现,他的所是和所做都是必然如此的,是不可能不如此的。我相信这个学说是错误的,但我在这篇文章中并没有证明这点,或者说我并没有驳斥决定论,而且我也怀疑这种证明或者驳斥是否可能。我的唯一用心是问自己这两个问题:为什么哲学家或其他人认为人类是完全被决定的?如果他们是这样认为的,那么,这与一般所理解的正常的道德情操及行为是否相容?

我的观点是,主要有两个理由支持人的决定论的学说(注:伯林自己并不认同这两种学说,而是在叙述这两种学说的过程中对它们进行反驳)。

第一个理由是,既然自然科学是整个人类历史中也许最成功的故事,那么假设只有人不服从由自然科学家发现的自然规律,便是非常荒谬的。这的确就是十八世纪的phibsophes(哲人们)所坚持的。当然,问题并不是人是否完全不受这种自然规律决定——只有疯子才会坚持人不依赖他的生物学或心理学结构,不依赖于环境或自然规律。关键的问题是:他的自由是否因此完全被杜绝?是不是还存在着某个角落,在其中他可以做他选择的事情,而不是被前在的原因决定去做这种选择?在自然领域中这也许是个很小的角落,但是除非这个角落存在,他的作为自由的存在物的意识——这种意识无疑是普遍的;绝大多数人相信这种观点,即虽然他们的行为中有些是机械的,有些却是服从他的自由意志的——才不至成为一种巨大的幻觉^这种意识自从人类开始时,即从亚当偷食禁果时就存在了。亚当虽然被告知不要偷食禁果,似偷食了以后也没有这样回答:“我禁不住这样做,我并不是自由地这样做的,是夏娃强迫我这样做的。”

第二个理由是,它把人们做的好多事情的责任,推到非人的原因上面,从而使他们对自己的所作所为有无需负责任的感觉。当我犯了一个错误,或者做了一件坏事,或犯了什么罪,或做了我或其他人认为是坏的或不幸的事情,我会说:“我怎么能够避免得了呢?我就是被教育这样做的”;或者,“这是我的天性,自然规律应该对此负责”;或者,“在我所属的那个社会、阶级、教会、民族中,每个人都是这样做的,而且没有人谴责这样做”;或者,“从心理学上,我是受我的父母彼此之间的行事方式以及他们对我的行事方式决定的,是受我置身其中的经济与社会状况决定的,或者是被迫这样做的,无法做其他选择的”;或者干脆,“我是在执行命令”。

与此相反,大多数人相信每个人都至少能够做出两种选择,两种他能够实现的可能性。当艾希曼说“我杀死犹太人是因为我被命令如此;如果我不这样做我自己也会被杀死”时,人们可能会说:“我觉得你不太可能会选择被杀,但是从原则上讲如果你决定这么做,你就可以这样选择。并不真的存在像自然界中那样的强迫,导致你做出你的行为。”你可能会说,当面临巨大危险时,期望每个人都如此行事是不合理的。的确如此,但是不管多么不可能,在他们“能够”作此选择这一字面意义上,他们都应该决定这么做。殉难是不能期望的,但是殉难是可以接受的,不管其概率有多么小。而且这正是它如此值得称道的原因。

这就是历史上人们接受决定论的理由。但是如果他们接受决定论,那么至少存在着一个逻辑上的困难。这意味着我们不可能对任何人这样说:“你已经这样做了吗?你为什么非要这样做不可?”隐藏在这种说法下面的假定是,他其实可以不这样做,或是可以做其他事情的。我觉得正是我们的全部日常道德观点(在其中我们可以谈及责任与义务、对与错、道德褒贬)——也就是当人们不是被迫行事时(他们能够以另一种方式行事),他们因其所作所为而受到的称赞或谴责、奖励或惩罚——我们日常道德依赖于其上的这种信念与实践的网络,假定了责任的观念;而正是责任使得在黑与白、对与错、快感与义务之间做出选择成为必要;同样,在更广泛的意义上,使得在生活方式、政府形式与整个道德价值星丛中做出选择成为必要——不管他们有没有意识到,大多数人实际上都是根据这些价值星丛来生活的。

如果决定论被接受,那么,我们的词汇就要做出非常根本的改变。我并不是说这事从原则上讲不可能,但是它的确不可能为绝大多数人所承受。在最好的情况下,美学将代替道德。你会羡慕或赞扬某些人的帅气、慷慨或精通音乐,但这不是他们的选择的结果,而是“他们被造就”的结果。道德赞扬也将不得不采取同样的形式:如果我因为你冒着生命危险救我而赞扬你,那么我的意思是说,值得惊叹的是你被如此造就,以致无法避免这样做;而且我非常高兴我遇到的是某个确确实实被决定要去救我的人,而不是一个被决定故意朝另一边看的人。值得尊敬与不值得尊敬的行为、享乐主义与英雄般的殉道、欺诈与真诚正派等等,所有这些都变得像漂亮与丑陋、高与矮、老与少、黑与白、英国或意大利父母所生一样,是我们无法改变的。因为一切都被决定好了。我们可能会希望事情变得如我们所愿,但我们不能为此做些什么——我们被如此造就,以致除了依某种特殊方式行事外无法做任何别的事情。事实上,行动的概念本身就意味着选择;但是如果选择本身是被决定了的,那么在行动与纯粹的动作之间有什么区别呢?

对我来说非常矛盾的是,某些政治运动一方面要求牺牲,另一方面却又持决定论的信念。例如,马克思主义是建立在历史决定论——社会在达到完美境界之前必须经过若干不可避免的阶段——基础上的,它责令人从事痛苦而危险的行动、强迫与斗争,这样一些对于行动者与受动者同样痛苦的事情;但是如果历史真的不可避免地带来完美社会,那么一个人为什么还要为这样一种据说不需要人帮助也会达到其适当而幸福的终点的过程牺牲性命呢?不过,存在着一种古怪的人类情感,即,如果天意在你这一边,你的事业必胜,那么,就像马克思所说的那样你必须牺牲你的生命以缩短这个进程,从而带来新秩序临近的阵痛。不过,是不是那么多的人真的都能被说服去面对这些危险,以缩短那种无论他们行动或不行动都会导致幸福的进程呢?这个问题总是使我、同时也使其他人感到困惑。

我在这个讲座中讨论的问题,一直是具有争论性的问题,它以往被激烈地讨论与争论着,也仍将被激烈地讨论与争论。


关于自由

我的另一篇讨论自由的讲演题目是《两种自由概念》。这是我就任牛津大学教授讲席的致辞。它的要点是区分自由的两种观念,即消极与积极自由。关于消极自由,我指的是不存在阻碍人行动的障碍。除了由外部世界,或支配人类的生物的、生理的和心理的规律所产生的阻碍外,还存在着缺乏政治自由的阻碍——这是我的讲演的核心。在缺乏政治自由的地方,这些阻碍就是人为的,不管是有意的还是无意的。消极自由的程度取决于这种人为阻碍存在与否,也就是说取决于我不被人为的制度、纪律或某些特定人类的活动所阻止,而自由地沿这条或那条道路前进的程度。

说消极自由仅仅意味着自由地做我喜欢做的事情,这是不够的,因为在那种情况下,我可以简单地遵循古代斯多鳴派消灭欲望的方法,使自己从实现欲望的障碍中解放出来。但是这条路径,即逐渐消除会导致障碍产生的欲望,最后会导致人类逐渐失去其自然的、有活力的活动;换句话说,处于最完美的自由状态的人将是那些死者,因为在他们那里既不存在欲望也不存在障碍。但是我心目中的消极自由,指的仅仅是一个人能够顺着走的那些道路的条数,至于他走不走,那是另一回事。这是政治自由的两个基本含义的第一个。

有些人不赞同我的观点,坚持说自由必须是一种三重关系:我克服、清除或摆脱障碍仅仅是为了做某件事,即自由地做某个或某些既定的行动。但我不接受这种说法。当一个人身陷囹圄或被绑在树上时,他就是不自由的;不自由的最基本的含义就是如此。这种状态中的人唯一寻求的,是打碎他的锁链,逃离监狱,他并不必然是为了实现某个特殊的行动。当然,在更大的意义上,自由意味着摆脱社会或其制度的统治,摆脱某种过分的道德或物质力量所施加的作用,或者摆脱任何关闭行动的可能性的东西——这些可能性本来是可以开放的。这就是我所说的“免于……的自由”。

自由的另外一个核心含义是“做……的自由”。如果我的消极自由通过对“我被控制到何种程度?”这个问题的回答而得到限定,那么,自由的第二个含义,是通过对“谁控制我?”这个问题的回答来限定的。既然我们说的是人为的障碍,那么我就可以问:“谁决定我的行为、生命?我是否能自由地依我选择的方式行事?或者,我是否处于别的控制力量的命令之下?我的行动是不是受父母、学监、牧师、警察的决定?我是不是处于法律制度、资本主义秩序、奴隶主、政府(君主制的、寡头制的和民主制的)的约束之下?我的行动的可能性也许受到限制,但是它们被如何限制?代表我的那些人是谁?他们可以使用的权力有多大?”

这就是我想要探讨的“自由”的两个核心含义。我认识到它们是不同的,是对两种不同性质的问题的回答;它们虽然同源,但在我看来它们却并不冲突,也就是说对其中一种问题的回答并不必然决定对另一种问题的回答。

两种自由都是人类的终极目的,两者都必需受到限制,两种概念在人类历史上都可能被滥用。消极自由可能被解释成经济的自由放任,据此,矿场主以自由的名义被允许在矿井下摧毁儿童的生命,或者工厂主被允许去摧毁工厂中工人的健康与人格。但是在我看来,那是一种滥用,而不是这个概念对于人类的基本含义。同样,告诉一个穷人说虽然他支付不起,但他完全有自由在一家昂贵的饭店拥有一个房间,这么说无异于嘲弄。但是这种说法也是一种混淆。他的确有在那里租用一间房子的自由,但没有手段使用这种自由。而他之所以没有这种手段,可能是因为一种经济制度阻碍他获得比他现在更多的收入;但这是一种对赚钱的自由的剥夺,而不是对租用房间的自由的剥夺。这听起来好像是一种学究式的区分,但是对于经济自由与政治自由的讨论却是非常关键的。

从历史上看,积极自由的观念甚至导致了更加可怕的滥用。谁对我的生命下命令?我。真的是我吗?无知、混乱、处处受无法控制的激情与的名义。这正是积极自由观念常常陷入的最大的滥用:不管专制来源于……领袖、国王、法西斯独裁者,还是来自极权式的教会或阶级或国家的主人,它都试图在人性中寻找被禁锢的“真实”自我,并“解放”它,以便这个自我能够达到那些发号施令者的水平。

这就回到了一种天真的观念:每一个问题都只有一个正确的答案:如果我知道这个正确的答案而你不同意我,那是因为你无知;如果你知道真理,你必然会相信我所相信的;如果你想不服从我,只能说明你是错误的,因为那个真理并没有像显示给我那样显示给你。这种说法替人类历史上一些最令人发指的压制与奴役形式辩护;而且这的确是积极自由观念的最危险、最凶残的含义,特别是在我们这个世纪。

从那以后,两种自由观念及它们的被歪曲的形式,在西方以及其他地方的大学里,成为激烈的讨论与争论的中心,今天仍然如此。

18
6

微软具有里程碑意义的Visual Studio 2022 Preview 1已经正式发布,虽然没有增加新功能,但是这个IDE重点支持64位。与此同时,微软也发布了.NET 6 Preview 5。

https://devblogs.microsoft.com/visualstudio/visual-studio-2022-preview-1-now-available/

https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-5/

https://devblogs.microsoft.com/dotnet/announcing-net-maui-preview-5/

微软在曾经在4月份在官方的博客文章种宣布了VS2022将会第一次支持64位,不再局限于4GB的内存限制,通过Windows上的64位的Visual Studio,你可以打开,编辑、运行和调试非常复杂的解决方案。

微软通过一个Gif视频展示64位的优势,最新版本的Visual Studio 2022可以轻松打开包含约1600个项目和大约300000个文件的解决方案。

微软在6月17日的文章 Visual Studio 2022 Preview 1 now available!,关键目标是测试和调整新 64 位平台的可扩展性!这是一个巨大的变化,影响到IDE的每一个部分。微软呼吁早期采用者开发者帮助开展这项工作,称"我们需要您的反馈"。VS 2019 功能不包括在预览 1:

Web实时预览
仪器分析仪
Azure 云服务项目支持
T-SQL 调试器
Web负载测试和测试控制器/测试代理
Azure数据湖
Coded界面测试
DotFuscator
内置 IDE 集成
智能提示的代码查找并替换

64 位版本Visual Studio 2022 Preview 1 三个版本的早期版本(社区、专业版和企业版) ,现在已经可以下载了:https://visualstudio.microsoft.com/zh-hans/vs/preview/vs2022/

09
6

关于自然景观和人文景观

0
归档:2021年6月分类:点滴生活

今天读到王小波的文章《自然景观和人文景观》,他写出了我对国内的乡村一直很想说的话,我认为他的这篇文章到现在都还没有过时,从我自己的村子到北京这座城市,现在还是如此。


王小波:自然景观和人文景观

我到过欧美的很多城市,美国的城市乏善可陈,欧洲的城市则很耐看。比方说,走到罗马城的街头,古罗马时期的竞技场和中世纪的城堡都在视野之内。这就使你感到置身于几十个世纪的历史之中。走在巴黎的市巾心,周围是漂亮的石头楼房,你可以在铁栅栏上看到几个世纪之前手工打出的精美花饰。英格兰的小城镇保留着过去的古朴风貌,在厚厚的草顶下面,悬挂出木制的啤酒馆招牌。我记忆中最漂亮的城市是德国的海德堡,有一座优美的石桥夹在内卡河上,河对岸的山上是海德堡选帝侯的旧官堡。可以与之相比的有英国的剑桥,大学设在五六百年前的石头楼房里,包围在常春藤的绿荫里——这种校舍不是任何现代建筑可比。比利时的小城市和荷兰的城市,都有无与伦比的优美之处,这种优美之处就是历史。相比之下,美国的城市很是庸俗,塞满了乱糟糟的现代建筑。他们自己都不爱看,到了夏天就跑到欧洲去度假——历史这种东西,可不是想有就能有的呀。

有位意大利的朋友告诉我说,除了脏点、乱—点,北京城很像一座美国的城市。我想了一下,觉得这是实情——北京城里到处是现代建筑,缺少历史感。在我小的时候就不是这样的,那时的北京的确有点与众不同的风格。举个例子来说,我小时候作在北京的郑工府里,那是一座优美的古典庭院,眼看着它就变得面门全非、塞满了四四方方的楼房,丑得要死。郑王府的遭遇就是整个北京城的缩影。顺便说一句,英国的牛津城里,所有的旧房子,屋主有翻修内部之权,但外观一毫不准动,所以那座城市保持着优美的旧貌。所有的人文景观属于我们只有一次。假如你把它扒掉,再重建起来就不是那么回事了。

这位意大利朋友还告诉我说,他去过山海关边的老龙头,看到那些新建的灰砖城楼,觉得很难看。我小时候见过北京城的城楼,还在城楼边玩耍过,所以我不得不同意他的意见。真古迹使人留恋之处,在于它历经沧桑直至如今,在它身边生活,你才会觉得历史至今还活着。要是可以随意翻盖,那就会把历史当作可以随意捏造的东西,一个人尽可夫的娼妇;这两种感觉真是大不相同。这位意大利朋友还说,意大利的古迹可以使他感到自己不是属于一代人,而是属于一族人,从亘古到如今。他觉得这样活着比较好,他的这些想法当然是有道理的,不过,现在我们谈这些已经有点晚了。

谈过了城市和人文景观。也该谈谈乡村和自然景观——谈这些还不晚。房龙曾说,世界上最美丽的乡村就在奥地利的萨尔兹堡附近。那地方我也去过,满山枞木林,农舍就在林中。铺了碎石的小径一尘不染……还有荷兰的牧场,弥漫精心修整的人工美。牧场中央仓放干草的小亭子,油漆得整整齐齐,像是园林工人干的活;因为要把亭子造成那个样于,不但要手艺巧,还要懂什么是好看。让别人看到自己住的地方是—种美丽的自然景观,这也是一种作人的态度。谈论这些域外的风景不是本文土旨,主旨当然还是讨论中国。我前半辈子走南闯北,去过国内不少地方,就我所见,贫困的小山村,只要不是穷到过不下去,多少还有点样。到了靠近城市的地方,人也算有了点钱,才开始难看。家家户户房子宽敞了,院墙也高了,但是样子恶俗,而且门前渐渐和猪窝狗圈相类似。到了城市的近郊,到处是乱倒的垃圾。进到城里以后,街上是干净了,那是因为有清洁工在扫。只要你往楼道里看一看,阳台上看一眼,就会发现,这里住的人比近郊区的人还要邋遢得多。总的来说,我以为现在到处都是既不珍惜人文景观、也不保护自然景观的邋遢娘们邋遢汉。这种人要吃,要喝,要自己住得舒服,别的一概不管。

我的这位意大利朋友是个汉学家。他说,中国入只重写成文字的历史,不重保存环境中的历史。这话从—个意大利人嘴里说出来,叫人无法辩驳。人家对待环境的态度比我们强得多。我以为,每个人都有—部分活在自己所在的环境中,这一部分是不会死的,它会保存在那里,让后世的人看到。住海德堡,在剑桥,在萨尔兹堡,你看到的不仅是现世的人,还有他们的先人,因为世世代代的维护,那地方才会像现在这样漂亮。和青年朋友谈这些,大概还有点用。

08
6
原文:bit.ly/3wFqDy9
作者:Daniel
译者:王亮

.NET 6 预览版 4 现已发布,其中包括对 ASP.NET Core 的许多新改进。

下面是此次预览版中 ASP.NET Core 的更新内容:

1 开始使用

要开始使用 .NET 6 Preview 4 中的 ASP.NET Core,请安装 .NET 6 SDK[1]。

如果你在 Windows 上使用 Visual Studio,我们建议安装 Visual Studio 2019 16.11 的最新预览版。如果你在 macOS 上,我们建议安装 Visual Studio 2019 for Mac 8.10 的最新预览版。

2 升级一个现有的项目

要将一个现有的 ASP.NET Core 应用程序从 .NET 6 Preview 3 升级到.NET 6 Preview 4。

将所有 Microsoft.AspNetCore. 引用包更新为 6.0.0-preview.4.

更新所有 Microsoft.Extensions. 引用包更新为 6.0.0-preview.4.

请参阅 .NET 6 中 ASP.NET Core 的完整中断变化列表[2]。

3 引入最小 API

在 .NET 6 中,我们为 Web 应用的托管和路由引入了最小 API。这为使用 .NET 构建第一个 Web 应用程序以及想要构建小型微服务和 HTTP API 的开发者打开了大门。这些精简的 API 提供了 ASP.NET MVC 的优点。

要尝试创建一个最小 API,请创建一个新的 ASP.NET Core 空 Web 应用。

dotnet new web -o MinApi

只需一个文件和几行代码,你现在就有一个功能齐全的 HTTP API。

file

4 新的路由 API

新的路由 API 允许用户路由到任何类型的方法。这些方法可以使用类似控制器的参数绑定、JSON 格式化和 Action 结果。

之前(使用现有的 Map APIs):

app.MapGet("/", async httpContext =>
{
    await httpContext.Response.WriteAsync("Hello World!");
});

现在(使用新的 Map 重载):

app.MapGet("/", (Func<string>)(() => "Hello World!"));

5 C# 10 的改进

这些 API 已经利用了较新的 C# 特性,如顶层语句。在今年晚些时候与 .NET 6 一起发布的 C# 10 中,体验将变得更好。例如,不再需要明确地把类型转换成 (Func)。下面的图片展示了 C# 10 支持的特性:

file

开发者从使用类和方法到使用 lambda,拥有和使用 MVC 控制器及属性操作一样的功能。

6 新的托管(hosting) API

新的空 Web 模板使用的是 .NET 6 Preview 4 中引入的新的托管模式。

var app = WebApplication.Create(args);

app.MapGet("/", (Func<string>)(() => "Hello World!"));

app.Run();

你并不局限于只使用新的路由 API。下面是一个 Web 应用程序的例子,它被更新为使用新的托管模式,配置服务和添加中间件。

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" });
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Api v1"));
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

新的托管 API 减少了配置和启动 ASP.NET 应用程序所需的模板数量。

7 性能

这些新的路由 API 的开销比基于控制器的 API 少得多。使用新的路由 API,ASP.NET Core 能够在 TechEmpower[3] JSON 基准测试中达到约 80 万 RPS,而 MVC 则达到约 50 万 RPS。

file

异步流

ASP.NET Core 现在支持从控制器 Action 一直到响应的 JSON 格式化器的异步流。从 Action 中返回 IAsyncEnumerable,在发送之前不再在内存中缓冲响应内容。这有助于在返回可异步枚举的大型数据集时减少内存使用。

请注意,Entity Framework Core 提供了用于查询数据库的 IAsyncEnumerable 的实现。在 .NET 6 中,ASP.NET Core 对 IAsyncEnumerable 的支持有所改进,可以使 EF Core 与 ASP.NET Core 的使用更加高效。例如,下面的代码在发送响应前将不再把 Products 数据缓冲到内存中:

public IActionResult GetProducts()
{
    return Ok(dbContext.Products);
}

然而,如果你已经将 EF Core 设置为使用懒加载,这种新的行为可能会导致在数据被枚举时由于并发的查询执行而产生错误。你可以通过自己缓冲数据来恢复到以前的行为:

public async Task<IActionResult> Products()
{
    return Ok(await dbContext.Products.ToListAsync());
}

有关这一行为变化的更多细节,见相关公告[4]。

8 HTTP 日志中间件

HttpLogging 是一个新的内置中间件,可以记录 HTTP 请求和 HTTP 响应的信息,包括头信息和整个 Body。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpLogging();
}

HttpLogging 中间件提供了以下日志:

HTTP 请求信息

普通属性

头信息

请求 Body

HTTP 响应信息

为了配置 HTTP 日志中间件,你可以在对 ConfigureServices() 的调用中指定 HttpLoggingOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpLogging(logging =>
    {
        // Customize HTTP logging here.
        logging.LoggingFields = HttpLoggingFields.All;
        logging.RequestHeaders.Add("My-Request-Header");
        logging.ResponseHeaders.Add("My-Response-Header");
        logging.MediaTypeOptions.AddText("application/javascript");
        logging.RequestBodyLogLimit = 4096;
        logging.ResponseBodyLogLimit = 4096;
    });
}

这会在日志中产生新的带有 Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware 类别的 HTTP 请求信息。

关于如何使用 HTTP 日志的更多信息,请看 HTTP 日志文档[5]。

9 使用 Kestrel 作为默认启动

file

对于在 .NET 6 Preview 4 中创建的所有新项目,我们已将默认的启动配置文件从 IIS Express 改为 Kestrel。在开发应用程序时,启动 Kestrel 的速度明显加快,并带来了更灵敏的体验。

IIS Express (ms) Kestrel (ms) % change
Debugging 4359 2772 36%
No debugging 1999 727 64%

IIS Express 仍然可以作为启动项,用于 Windows 认证或端口共享等情况。

10 IConnectionSocketFeature

IConnectionSocketFeature 功能使你能够访问与当前请求相关的底层接受 socket。它可以通过 HttpContext 上的 FeatureCollection 访问。

例如,下面的应用程序在接受 socket 上设置 LingerState 属性:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions => listenOptions.Use((connection, next) =>
    {
        var socketFeature = connection.Features.Get<IConnectionSocketFeature>();
        socketFeature.Socket.LingerState = new LingerOption(true, seconds: 10);
        return next();
    }));
});
var app = builder.Build();
app.MapGet("/", (Func<string>)(() => "Hello world"));
await app.RunAsync();

11 改进单页应用(SPA)模板

略...(译注:文字太长,懒得翻译了,主要 VS 中的 SPA 模板我从来不用)

12.NET 热重载

最新的 Visual Studio 预览版对.NET Hot 热重载有一些初步的支持。你可能已经注意到在调试你的应用程序时,新的 Apply Code Changes 按钮和调试选项。

Apply Code Changes 按钮将用你所作的代码修改来更新正在运行的应用程序,甚至不需要保存。下面是一个更新 Counter 组件的例子,它的增量从 1 改为 2。请注意,一旦修改被应用,当前的计数不会丢失:

file

Visual Studio 中的 .NET 热重载支持仍在进行中,因此在 ASP.NET Core 应用程序中使用它时有一些限制:

你必须在连接调试器的情况下运行以应用更改。

代码修改只能应用于 C# 文件--还不支持对 Razor 文件(.razor, .cshtml)的修改。

已应用的更改还不能强制更新用户界面,因此需要手动触发用户界面更新。

目前不支持 Blazor WebAssembly 应用程序。

所有这些限制都在解决中,并将在未来的 Visual Studio 更新中得到解决。敬请关注!

如果你通过 dotnet watch 使用 .NET 热重载,修改将被应用于 ASP.NET Core 托管的 Blazor WebAssembly 应用程序。如果你刷新浏览器,修改也会重新应用到你的 Blazor WebAssembly 应用程序。

要了解更多关于.NET 热重载的信息,你可以在我们的博文中获得所有细节:介绍.NET 热重载[6]。

13 Razor 中的泛型约束

在 Razor 中使用 @typeparam 指令定义通用类型参数时,你现在可以使用标准的 C# 语法指定泛型约束。

@typeparam TEntity where TEntity : IEntity

14 Blazor 错误边界

Blazor 错误边界提供了一种方便的方式来处理组件层次结构中的异常情况。为了定义一个错误边界,使用新的 ErrorBoundary 组件来包裹一些现有的内容。只要一切运行顺利,ErrorBoundary 组件将渲染其子内容。如果一个未处理的异常被抛出,ErrorBoundary 会渲染一些错误 UI。

例如,我们可以像这样在默认 Blazor 应用程序的布局中添加一个错误边界:

<div class="main">
  <div class="top-row px-4">
    <a href="https://docs.microsoft.com/aspnet/" target="_blank" rel="noopener">
      About
    </a>
  </div>

  <div class="content px-4">
    <ErrorBoundary> @Body </ErrorBoundary>
  </div>
</div>

该应用程序继续像以前一样运作,但现在我们的错误边界将处理未处理的异常。例如,我们可以更新 Counter 组件,在计数过大时抛出一个异常。


private void IncrementCount()
{
    currentCount++;
    if (currentCount > 10)
    {
        throw new InvalidOperationException("Current count is too big!");
    }
}

现在,如果我们过多地点击计数器,就会抛出一个未处理的异常,这将由我们的错误边界通过渲染一些默认的错误界面来处理。

file

默认情况下,ErrorBoundary 组件为其错误内容渲染了一个带有 blazor-error-boundary CSS 类的空 div。这个默认界面的颜色、文本和图标都是在应用程序中使用 CSS 定义的,所以你可以自由地定制它们。你也可以通过设置 ErrorContent 属性来改变默认的错误内容。

<ErrorBoundary>
  <ChildContent> @Body </ChildContent>
  <ErrorContent>
    <p class="my-error">Nothing to see here right now. Sorry!</p>
  </ErrorContent>
</ErrorBoundary>

因为我们在布局中定义了错误边界,一旦抛出一个异常,不管我们导航到哪个页面我们都能看到错误内容。一般来说,错误边界的范围最好比这更窄,但我们可以选择在随后的页面导航中通过调用错误边界的恢复方法将错误边界重置为非错误状态。

<ErrorBoundary @ref="errorBoundary">
    @Body
</ErrorBoundary>
...

@code {
    ErrorBoundary errorBoundary;

    protected override void OnParametersSet()
    {
        // On each page navigation, reset any error state
        errorBoundary?.Recover();
    }
}

15 Blazor WebAssembly 的 AOT 编译

Blazor WebAssembly 现在支持 AOT(ahead-of-time) 编译,你可以将你的 .NET 代码直接编译为 WebAssembly,以显著提高运行时性能。现在 Blazor WebAssemby 应用程序使用 WebAssembly 中实现的 .NET IL 解释器运行。由于 .NET 代码是被解释的,通常这意味着在 WebAssembly 上运行的 .NET 代码比在正常的.NET 运行时要慢得多。.NET WebAssembly AOT 编译通过将你的 .NET 代码直接编译成 WebAssembly 来解决这个性能问题。

AOT 编译你的 Blazor WebAssembly 应用程序,对于 CPU 密集型任务来说,其性能的提高是相当显著的。例如,下面的片段显示了使用相同的 Blazor WebAssembly 应用程序进行一些基本图像编辑的比较,首先使用解释器,然后是 AOT 编译。AOT 编译后的版本运行速度快了五倍以上。

file

你可以在 GitHub 上查看这个 PictureFixer[7] 的代码。

.NET WebAssembly AOT 编译需要一个额外的构建工具,必须作为一个可选的 .NET SDK 工作负载来安装才能使用。要安装 .NET WebAssembly 构建工具,请运行以下命令:

dotnet workload install microsoft-net-sdk-blazorwebassembly-aot

为了在你的 Blazor WebAssembly 项目中启用 WebAssembly AOT 编译,在你的项目文件中添加以下属性:

true

然后 AOT 将你的应用程序编译成 WebAssembly,发布应用程序。使用 Release 配置发布将确保 .NET IL 链接也被运行,以减少发布应用程序的大小。

dotnet publish -c Release

WebAssembly AOT 编译只在项目发布时进行。当项目在开发过程中运行时,它并不使用。这是因为 WebAssembly AOT 编译可能需要一段时间。

AOT 编译的 Blazor WebAssembly 应用程序的大小通常比作为 .NET IL 的应用程序要大。在我们的测试中,大多数 AOT 编译的 Blazor WebAssembly 应用程序大约大2倍,不过这取决于具体的应用程序。这意味着,使用 WebAssembly 的 AOT 编译,可以用加载时间的性能换取运行时间的性能。这种权衡是否值得,取决于你的应用程序。

16 .NET MAUI Blazor 应用

Blazor 能够用 .NET 构建客户端 Web UI,但有时你需要的东西比 Web 平台提供的更多。有时你需要完全访问设备的本地功能。现在,你可以在 .NET MAUI 应用程序中托管 Blazor 组件,以使用 Web UI 构建跨平台的本地应用程序。这些组件在.NET 进程中原生运行,并使用本地互操作通道向嵌入式 Web 视图控件渲染 Web UI。这种混合方法为你提供了本地和网络的优点。你的组件可以通过 .NET 平台访问本地功能,并呈现标准的 Web UI。.NET MAUI Blazor 应用程序可以运行在任何 .NET MAUI 可以运行的地方(Windows、Mac、iOS 和 Android),尽管我们对 .NET 6的主要关注是在桌面场景。

要创建一个 .NET MAUI Blazor 应用程序,你首先需要在开发机器上配置 .NET MAUI。最简单的方法是使用 maui-check 工具。要安装 maui-check 工具,请运行:

dotnet tool install -g Redth.Net.Maui.Check
然后运行 maui-check 来获取 .NET MAUI 工具和依赖。有关开始使用 .NET MAUI 的其他信息,请参考 GitHub 上的 wiki 文档。

一旦一切安装完毕,使用新的项目模板创建一个 .NET MAUI Blazor 应用程序:

dotnet new maui-blazor -o MauiBlazorApp
你也可以使用 Visual Studio 创建一个 .NET MAUI Blazor 应用程序:

file

.NET MAUI Blazor 应用程序是 .NET MAUI 应用程序,它使用 BlazorWebView 控件将 Blazor 组件渲染到一个嵌入式 Web 视图中。应用程序的代码和逻辑位于 MauiApp 项目中,该项目被设置为多目标 Android、iOS 和 Mac Catalyst。MauiApp.WinUI3 项目用于为 Windows 构建,而 MauiApp.WinUI3(Package) 项目则用于为 Windows 生成 MSIX 包。最终,我们希望将对 Windows 的支持合并到主应用程序项目中,但现在这些独立的项目是必要的。

在 MauiApp 项目的 MainPage.xaml 中设置了 BlazorWebView 控件:

<b:BlazorWebView HostPage="wwwroot/index.html">
    <b:BlazorWebView.RootComponents>
        <b:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
    </b:BlazorWebView.RootComponents>
</b:BlazorWebView>

该应用程序的根 Blazor 组件在 Main.razor 中。其余的 Blazor 组件都在 Pages 和 Shared 目录下。请注意,这些组件与默认 Blazor 模板中使用的组件相同。你可以在你的应用程序中使用现有的 Blazor 组件,而不用改变代码,或者引用包含这些组件的现有类库或包。应用程序的静态资源在 wwwroot 文件夹中。

17 Windows

要在 Windows 下运行该应用程序,你需要使用 Visual Studio 构建和运行。

选择 MauiBlazorApp.WinUI3(Package) 项目作为你的启动项目:

file

同时为目标平台选择 x64:

file

然后你可以按 F5 或 Ctrl+F5,使 WinUI 应用作为本地 Windows 桌面应用运行。

file

18 Android

要在 Android 上运行该应用程序,首先使用 Android SDK 或 Android 设备管理器启动 Android 模拟器。

然后使用以下命令从 CLI 运行该应用程序:

dotnet build MauiBlazorApp -t:Run -f net6.0-android

要从 Visual Studio 在 Android 上运行,选择 MauiBlazorApp 项目作为启动项目:

file

然后在运行按钮下拉菜单中选择 net6.0-android 作为目标框架:

file

然后你可以点击 F5 或 Ctrl+F5,使用安卓模拟器运行该应用程序:

file

19 iOS 和 Mac Catalyst

译注:Mac Catalyst 是一个帮助开发者将 iOS 应用移植到 macOS 上的服务。

要运行 iOS 或 Mac Catalyst 的应用程序,你需要使用一个运行 Big Sur 的 macOS 开发环境。你目前不能从 Windows 开发环境中运行 iOS 或 Mac Catalyst 的应用程序,尽管我们确实期望 .NET MAUI 将支持使用连接的 Mac 构建代理或使用热重启在连接的设备上运行 iOS 应用程序。

要运行 iOS 和 Mac Catalyst 的应用程序,请使用以下命令:

dotnet build MauiBlazorApp -t:Run -f net6.0-ios
dotnet build MauiBlazorApp -t:Run -f net6.0-maccatalyst

file

在这个版本中,.NET MAUI Blazor 应用程序有一些已知的限制:

组件范围内的 CSS 文件(.razor.css)还不能在主 .NET MAUI 项目中使用。这将在未来的更新中得到修复。

了解更多关于 .NET 6 Preview 4 中 .NET MAUI 的新内容[8]。

20 其他性能改进

略...(注:这部分列举了一些社区贡献的提高性能的 PR,没啥可翻译的,感兴趣的同学可以直接在英文原文点击链接查看。)

21 提供反馈

我们希望你喜欢此次 .NET 6 中的 ASP.NET Core 预览版。我们很想听听你对这个版本的体验。在 GitHub[9] 上提交 Issue,让我们知道你的想法。

感谢你尝试使用 ASP.NET Core!

文中链接:

[1]. https://dotnet.microsoft.com/download/dotnet/6.0
[2]. https://docs.microsoft.com/dotnet/core/compatibility/6.0#aspnet-core
[3]. https://www.techempower.com/benchmarks/
[4]. https://github.com/aspnet/Announcements/issues/463
[5]. https://docs.microsoft.com/aspnet/core/fundamentals/http-logging
[6]. https://aka.ms/build2021-hotreload
[7]. https://aka.ms/picture-fixer
[8]. https://devblogs.microsoft.com/dotnet/announcing-net-maui-preview-4
[9]. https://github.com/dotnet/aspnetcore/issues

公告栏

欢迎大家来到我的博客,我是dodoro,希望我的博客能给你带来帮助。