面向初学者的.NET

2020-07-23 17:24:08

您好,我刚刚开始学习c#,我即将开始学习Mosh Hamedani的一门关于Udemy的课程,名为“初学者的C#基础:通过编码学习C#基础”。我看得出他使用的是.NET Framework,但我读到.NET Core是较新的,是未来吗?我真的不知道从哪里开始,如果有人能帮我的话,我会很高兴的。我想学习C#,以便更好地理解OOP,并学习一种编程语言来帮助我的大学课程。谢谢。

首先,祝贺作者学习了C#,这是一个很好的编程语言选择,并为更好地理解面向对象编程(OOP)的概念付出了额外的努力!我真心希望他们在学习.NET的过程中会有很好的体验,最重要的是,他们会喜欢学习一些新技能,并在学习过程中获得乐趣!我还记得我开始编程的时候(20多年前),那对我来说是多么有趣!看到有多少人回复了真正有帮助的答案,并为原始帖子提供了一些有用的指导,这也是一件很棒的事情!这真正证明了.NET社区是多么的支持和欢迎!然而,尽管有这些积极的观察,我仍然有点气馁,因为这样的问题一开始就不得不问。我并不是在暗示作者本身有什么过错--恰恰相反--我真的很同情他们,能够理解一个新的C#或F#开发人员可能面临的挣扎。这样的问题确实说明了这些年来.NET已经变得多么复杂。现在是退一步反思的好时机!

.NET有很高的认知进入门槛。我这么说的意思是,新的开发人员必须在他们的教育旅程中过早地迅速熟悉相当无聊和复杂的主题。特别是关于.NET、.NET Core、Mono、Xamarin之间的区别,以及C#、F#、VB.NET和什么是目标框架或运行时之间的关系的问题,对人们最初的学习体验几乎没有什么好处。大多数初来乍到的人只想阅读教程、看视频或上课,然后能够以一种简单而简单的方式应用他们新学到的技能。理想情况下,教育材料,如几个多月前购买的在线课程或书籍,今天应该仍然适用。不幸的是,这两个都不适用于.NET。事实上,几乎可以说,一年多前编写的任何内容在今天基本上都已经过时了。只要想想即将发布的.NET5,以及它将如何使几个月前教给我们的大部分课程失效。另一个突出的例子是非常短暂的.NET标准。曾经盛行福音派,现在事实上已经死了。我个人认为微软、.NET团队以及在某种程度上更广泛的.NET社区在使.NET成为更适合初学者的语言方面失败了。我说这话是出于内心的好意。编程是一项非常强大的技能,可以让人们从各种背景中提升自己,我们对初学者来说越难,我们进入我们的职业就越排他性。我认为下一个十年的成功将取决于我们如何让一群全新的开发人员访问.NET,我认为为了改善目前的状况,还有一些真正的工作要做!

在你认为目前的复杂性在编程中是正常的,没有.NET本身特有的东西之前,我恐怕要证明你错了。请看一下PHP。PHP在过去几年中发展了很多,虽然它引入了更复杂的面向对象的概念并改进了性能,但它丝毫没有失去最初简单的美感。PHP是一门很好学的编程语言。初学者的内容就像沙滩上的沙子一样存在。在线社区、论坛、Reddits和会议都是首屈一指的。最重要的是,一个学生可以把一本几年前的PHP书传给另一个人,但他们仍然会从中获得很大的价值。这门语言可能已经向前发展了,但是很多在初学者水平上教授的东西在今天仍然是百分之百准确的。这是一个巨大的优势,像我这样的高级开发人员很容易忘记这一点。此外,语言和解释器之间的区别不是PHP新开发人员必须理解的。一个初学者不必把头脑绕在这些相对不重要的话题上才能开始。他们只知道他们已经安装了PHP并且运行正常。

另一个很好的例子(有很多很好的例子)是围棋。围棋根本不是一门新语言。它已经有10多年的历史了,尽管在语言、编译器和标准库方面有了巨大的改进,但它仍然忠于最初的简单设计。与PHP类似,新开发人员不必测试

不过,最令人沮丧的是,对一种语言的更改会给另一种语言带来额外的复杂性。

这三种语言之间的互操作问题对新开发人员来说是一个很大的负担,特别是当他们从C#以外的其他东西开始的时候。然而,尽管这可能很痛苦,但互操作问题并不是初学者必须面对的唯一复杂性。尝试以一种有意义的方式向C#新用户解释他们何时应该对标准类、接口、抽象类或具有默认方法实现的接口使用继承。这些选项之间的差异已经被淡化,以至于人们不能再用一个连贯的答案来解释这些差异。

以这个StackOverflow问题为例。下面接受的(且最受欢迎的)答案中描述的任何内容都不适用于今天使用默认方法实现的接口:

另一个很好的例子是种类越来越多的C#数据类型。什么时候适合创建数据类、不可变数据类、可变结构、不可变结构、元组类、命名元组的新概念或即将出现的记录类型?

经验丰富的.NET开发人员在何时使用这些类型时非常固执己见,根据初学者会问谁,或者他们会阅读哪个StackOverflow线程,他们很可能会得到非常不同的建议,而且往往是相互矛盾的。任何不认为这是一个大问题的人都必须严肃地否认这一点。学习一门编程语言本身就够难的了。在两个导师(你可能会尊敬的人)给你相互矛盾的建议的情况下,学习一门编程语言就更难了。

具有讽刺意味的是,许多新添加的语言和框架功能本应使.NET更容易学习:

(顺便说一句,很长一段时间以来,我一直是删除.csproj和.sln文件的坚定支持者,但之前微软员工为它们辩护,就好像有人冒犯了他们的家人,所以很高兴终于看到这个想法得到了一些支持!:)。

别误会我的意思,我同意斯科特的观点,这一特殊功能会让编写第一个Hello world应用变得比以前容易得多。然而,我们的朋友约瑟夫·伍德沃德(Joseph Woodward)提出了一个很好的观点,那就是没有什么是免费的:

这不仅仅是学习如何编写C#。学习.NET的很大一部分是阅读其他人的代码,这本身也变得更加困难:

虽然我确实喜欢并支持向C#添加更多功能的想法,但我不能忽视这样一个事实,即这也是要付出代价的。

一些人提出了一个很好的观点,认为现在可能是时候考虑让一些旧功能过时了:

无论一个人的个人观点是什么,特性膨胀肯定会成为C#社区日益关注的问题,而微软如果不倾听或者至少做一些笔记,那将是愚蠢的。

考虑到F#已经是一种函数式的第一种多范例语言,而且C#肯定也在朝着这个方向发展,也许有一天会有机会将这两种语言合并为一种语言?(是的,我敢提出来!)。要么这样,要么微软应该建立100%的功能对等,这样语言之间的互操作是无缝的,唯一的区别因素仍然是它们的语法-一个面向功能的第一次体验,另一个面向面向对象的等价语言。

如上所述,所有三种.NET语言都是从.NET独立发展而来的。C#正在向版本9发展,F#正在接近版本5,而VB.NET已经在版本16。同时,.NET Framework在版本4.8,.NET Core在版本3.1。不要让我开始使用Mono、Xamarin或ASP.NET。

现在我明白了,所有这些东西都是非常不同的,我正在比较苹果和橙子,但是一个新的开发人员怎么可能知道所有这些呢?所有这些组件都是独立的,但又足够相关,足以让新开发人员对下面这样的屏幕感到不知所措:

即使是有5年以上经验的.NET开发人员也很难消化上述信息。我知道这是事实,因为我在面试中经常问这个问题,很少能得到正确的解释。问题不是这些信息太冗长、错误或没有必要知道,而是不幸的是.NET已经变得如此庞大。事实上,它甚至更大,但我相信.NET团队已经尽了最大努力将这个屏幕压缩成尽可能简单的形式。我理解其中的困难--如果你有一个非常成熟和功能丰富的平台,那么就有很多需要解释的地方--但尽管如此,它看起来并不是特别性感。

与.NET相比,这是围棋初学者面临的认知负担:

它在各方面都要简单得多。诚然,这不是一个完全公平的比较,因为围棋被直接编译成机器代码,因此SDK和运行时之间并没有真正的区别,但我的观点仍然是一样的。当然还有很大的改进空间,我不认为我们今天在那里看到的是我们能做的最好的。

也许将语言、ASP.NET核心和.NET(核心)版本正式统一起来,每次发布一个连贯的发行版会有一些价值吗?幸运的是,.NET5是朝着这个方向迈出的正确的一步,但在我看来,还有更多的事情要做!

这可能会触动一些人的神经,但.NET的一个“大”问题是,微软到处都痴迷于.NET的想法。每一项新开发的目标都是将所有东西统一到一个大平台中,以迎合可以想象到的每一个可能的用例:

(多亏了本·亚当斯,我更新了这张图片,以代表.NET的全貌。本为自己的博客创作了这张图片,您可以在www.ageofascent.com/blog上阅读。)。

在许多方面,这很有意义,但所采取的角度造成的伤害大于帮助。虽然走在舞台上向潜在客户吹嘘你的产品可以解决他们现有和未来的所有问题是很有意义的,但当你真的想让来自各种不同行业的新开发人员加入时,这并不总是最好的方法。

将整个堆栈统一到一个.NET平台中并不是没有代价的。多年来,东西一直在移动,新的东西不断涌现,其他的东西也被丢弃了。就在最近,我不得不再次重新分解我的ASP.NET核心启动代码:

每一次为了统一而统一事物的尝试都会使简单的代码变得更加冗长。毫无疑问,前面的代码更容易理解。我赞同通用主机的概念,但人们不得不想知道开发人员实际想要将两台服务器组合成一台服务器的频率有多高?在我看来,必须有真正的好处才能证明复杂性是合理的,比如将一个构建器放在另一个构建器中!开发人员多久想要“创建”一个Web服务器,而不是“运行”它?我确信这些边缘情况确实存在,但是为什么不能对其他99.9%的正常发生的用例隐藏它们呢?

尽管构建器模式很好很有用,不管lambda表达式可能会给架构带来什么好处,但对于一个只想创建hello world web应用程序的C#新手来说,这简直是疯了!

Router:=...//等效于.NETif Err:=http.ListenAndServe(";:5000";,Router)中的Startup类;err!=nil{//Handle Err}。

微软的“瑞士军刀”方法以许多不同的方式给新的.NET开发人员带来了不必要的负担。

例如,以下是作为.NET CLI的一部分附带的所有默认.NET模板的输出(不包括Giraffe模板):

它们几乎不能放在一个屏幕上。再说一次,微软有Blazor作为WASM的答案,或者他们有WPF作为Windows的选项,这很好,但为什么这些东西都作为一个丑陋的东西一起发布呢?为什么不能只有一个控制台应用程序或类库的模板,然后再有一些解释如何下载更多内容的文本呢?这是一个经典的例子,.NET Everywhere正在以这种方式进入大多数用户!

一个新的.NET开发人员在开始编写一些基本代码之前,很少会想要淹没在选择的海洋中。大多数初来乍到的人只想设置最低限度的基础,以便启动和运行,并编写他们的第一行代码。他们甚至不在乎它是控制台应用程序还是ASP.NET核心应用程序。

我完全支持单一.NET的想法,它可以满足各种不同的需求,但它必须以一种不那么压倒性的方式应用。Visual Studio的新项目对话不需要与微软的营销幻灯片相匹配,DotNet的new命令也不需要为每种类型的应用程序提供模板。开发人员首先被派去开发一条业务线的Web应用程序,然后被告知要开发一款Windows窗体商店应用程序,然后又被要求开发一款游戏,这种情况并不经常发生。绝对没有人需要他们的机器上横跨十个不同行业的二十个不同的模板。

我的建议是优化初学者的.NET体验,根本不用担心高级开发人员。高级用户被称为高级用户是有原因的。如果高级开发人员想要从iOS切换到物联网开发,那么他们会知道在哪里可以找到工具。目前.NET CLI发布了15个!供用户选择的不同web应用模板。如果一个新的C#开发人员连有经验的.NET开发人员都摸不着头脑,他该如何决定正确的模板呢?微软必须明白,不是让每个工具或IDE都有一百万个不同的选项,并不意味着用户不知道这些选项确实存在。

在我看来,围绕.NET Everywhere的整个心态是完全错误的。这应该是一个积极的副作用,而不是目标。

我观察到的另一个问题是微软害怕被忽视。对于开发人员可能面临的几乎所有问题,微软都有解决方案。这是一项令人惊叹的成就,也是一件值得骄傲的事情(我是认真的),但同时微软也必须学会如何给开发人员一些空间。

当人们只看一种产品时,微软不会错过任何一次为整个产品做广告的机会。在做.NET开发吗?哦,看,这是Visual Studio,它可以帮你做到这一点!哦,顺便说一下,您可以直接部署到IIS!如果你想知道,IIS附带了Windows Server,它也可以在Azure中运行!啊哈,说到Azure,你知道吗,你也可以点击这个按钮,它会自动创建订阅并部署到云中。如果您不喜欢右击发布,我们还有Azure DevOps,这是一个功能齐全的CI/CD管道!当然没有压力,但是如果你现在就报名,我们会给你一个月的免费学分!无论如何,这只是一个友好的提醒,所以你知道,理论上我们提供全套服务,以防你需要!妈妈,看着我,看着我,现在看着我!

再说一次,我完全理解微软为什么要这么做(我相信这里面有很多好的用意),但它给人的印象是完全错误的,而且是完全相反的。

嘿,伙计们,看,我们现在不同了,我们是跨平台的,我们到处跑,我们希望你们有一个很棒的体验。这里有一些东西可以帮助你旅行。

嘿,.NET是微软的产品,而且它大多只能与其他微软产品一起使用,所以这里有一些你必须要用到的东西!

一方面,微软想要创建这个新品牌的开源、跨平台开发工具链,但另一方面,每当Visual Studio和Azure使用.NET时,他们就会推动它们。这是在传递复杂的信息,让新的开发人员感到困惑,削弱了.NET的实际才华,并对整个开发平台造成了巨大的伤害。令人沮丧的是,.NET对世界开放的程度越高,微软推动他们自己的专有工具的力度就越大。如今,当你看到一些最具标志性的.NET员工发表关于.NET的演讲时,只有50%的人是.NET,其余的都在宣传Windows、Edge和Bing。这不是大多数.NET开发人员看到的,在其他编程社区,如Node.js、Rust或Go中也不会出现这种情况。此外,如果有人不断地宣传每月微软的每一种新口味,那么随着时间的推移,他们也会失去开发人员的可信度。

这个问题,特别是答案真的很糟糕,贝卡

.