您可能会认为,要使用
foreach
循环,要迭代的collection 必须实现
IEnumerable
或IEnumerable<T>
。事实证明,这实际上并不是必需的。
所需要的是,集合的类型必须具有一个称为
GetEnumerator
的公共方法,并且必须返回某种类型,该类型具有一个名为Current
的public 属性获取器和一个公共方法
MoveNext
返回
bool
。如果编译器可以确定满足所有这些要求,则将生成代码以使用这些方法。
仅当不满足这些要求时,我们才会检查
对象是否实现
IEnumerable
或IEnumerable<T>
。这是很酷的东西。我能理解为什么埃里克知道这一点。他在编译器团队中,所以他必须知道。但是那些展示了如此深厚的知识而不是内部人员的人呢?
凡人(不在C#编译器团队中)如何找到类似这样的东西?
具体来说,这些人是否使用方法来系统地扎根此类知识,对其进行探索并对其进行内部化(使其自己拥有)?
#1 楼
首先,感谢您的客气话。如果您想深入了解C#,拥有语言规范,十年的设计说明,源代码,错误无疑是一个优势。数据库,而Anders,Mads,Scott和Peter就在大厅附近。我当然很幸运,对此毫无疑问。
但是,即使没有这些优势,仍然可以对这个主题有深入的了解。
回到Microsoft时,我正在使用Internet Explorer 3附带的JScript解释器。当时,我的经理告诉我了一些我所获得的最佳建议。他说,他希望我成为Microsoft公认的JScript语言的语法和语义方面的专家,并且我应该针对JScript的这些方面寻找问题并予以回答,以解决这个问题。特别是回答我不知道要回答的问题,因为那是我将从中学到的问题。那时,我认真地阅读了comp.lang.javascript和我们内部的Microsoft“ JS User”论坛,并听从了我经理的建议:当我看到一个关于我不知道答案的语言语义学的问题时,我的公司才能找到答案。到目前为止,我仍然对浏览器对象模型的工作方式一无所知。由于最近几年我一直专注于成为C#语言专家,因此我对基类库中各种类的工作方式一无所知。我很幸运,因为我有一份工作可以奖励特定的深造知识。如果您的工作或才干更适合成为通才,则深入研究可能对您不起作用。
撰写博客也非常有帮助;通过要求我向其他人解释复杂的主题,我不得不一直面对自己对各种主题的理解不足。
评论
不要拖延这个话题,但是在阅读了这个答案之后,我很好奇为什么您在这里或Stack Overflow上没有问任何问题。此时,您的同事,博客等是否足以满足您的需求?是否有比我们应该知道的更好的资源?
–马修·雷德(Matthew Read)
2012年6月1日22:38
也许您误解了他在说什么。违反直觉,他不是在问问题以学习东西,而是在回答问题。
–跳楼
13年11月1日13:01
@jhocking,“通过回答来学习”必须是我今年听说过的最深刻的事情之一。提供对其他人提出的问题的答案确实是一种非常有效的学习方法-您不仅可以自己学习该主题,还可以学习其他人如何看待该主题以及如何向他人解释。
–史蒂夫
20年3月28日在18:18
#2 楼
在对话的“专家”一到两次之后,我可以告诉您,很多时候,您对编程语言或系统的“深刻了解”通常是由于最近“专家”在努力一个月来解决完全相同的问题。在论坛上,人们可以选择要回答的问题尤其如此。甚至Jon Skeet和Eric Lippert之类的人也必须一次学习世界。他们一次都像其他任何人一样领会知识。评论
很好的一点。在进行长时间的研究时,我经常会发现由于我今天早些时候学到的东西,我现在可以回答一些问题。
–马修·雷德(Matthew Read)
2012年6月1日22:11
#3 楼
释义:Yogi Bhajan:“如果您想学习一些东西,请先阅读;如果您想了解一些东西,请先编写;如果您想掌握一些东西,
对其进行编程。”
编程就像终极的教学挑战。教计算机做某事需要您非常了解自己的东西-否则您将学习掌握它。
例如,如果您想学习物理学,请编写物理学引擎。如果您想学习国际象棋,请编写国际象棋游戏。如果您想学习更深的C#知识,请编写C#编译器(或其他工具)。
评论
编程也是一种以最明确的方式进行写作的适度尝试(当然要被人们阅读)。
–vpit3833
2011年7月12日在23:09
在我阅读国际象棋示例之前,这句话听起来很深刻。不幸的是,对国际象棋AI进行编程不会使您成为更好的国际象棋玩家(基本上是在Min-Max树中搜索)。仍然+1
– bughi
2012年8月23日在15:04
@bughi也许您可以掌握规则:D
–朱利奥·罗德里格斯(Julio Rodrigues)
2012年10月18日18:50
@bughi,“编程它”是一个非常广泛的术语,并不总是与编写代码有关!开箱即用。
–Nitesh Verma
13年8月24日在9:28
#4 楼
据我所知,学习此方法的方法是:从像Eric Lippert这样的人那里学习它
经验,然后直接解决问题。
第二种方法可能需要更长的时间,但可能会导致更深刻的理解(但并非总是如此)。
评论
或两者。 [15个字符]
– Michael K
2011年7月11日在20:40
#5 楼
我会说:在学习了相对有用的语言堆栈(完成一项实际工作所需的语言)之后,您可以执行最常见的任务,
停止学习直到您至少学习了至少一种语言为止。我认为,目前我们行业的问题之一是,人们在学习其他语言之前只学习该语言的前5-10%。一旦具备了完成一项工作中最常见任务的能力,便可以开始深入研究一件事。 (您可以在深入了解之后再回到广度,然后在两者之间来回走动。)深度解决问题。如果没有工作,请寻找开源任务来做或开始从事个人项目,这将使您不得不深入。如果您的工作没有有趣的问题,请考虑寻找更具挑战性的工作。
用一种语言阅读高级书籍(例如,对于SQl Server,这将包括有关性能调优和数据库内部知识的阅读),而不是在30天之内学习X。
在这里和其他需要阅读的地方阅读有趣的问题,并尝试自己解决问题。如果您想学习,尝试解决一些问题,而不先阅读其他答案。即使已经回答了该问题,如果您自己找到答案,您也会学到更多。您甚至可能会找到比这个问题更好的答案。
问一些较难的问题。评估给出的答案,而不仅仅是使用它们。确保了解答案为何有效或无效。使用这些答案作为研究的起点。
从该领域的知名专家那里找到一些好的技术博客,并阅读它们。
完成学习后,不要再扔掉知识了。学会保留。大多数专家不必查找通用语法。他们不必每次都遇到问题时就重新发明轮子,因为他们记得自己以前是如何解决类似问题的。他们可以将点连接起来,看看他们两年前做过的问题X与现在遇到的问题Y有何相似之处(令我惊讶的是,似乎很少有人能够像这样进行联系)。因此,他们有更多时间可用于研究更多有趣的主题。
评论
一个不错的答案。但是我不禁要问,如何在保留知识和点点滴滴方面做得更好?
–user39685
2012年10月3日15:02
我建议您记下所学内容。我开始在Evernote中进行此操作,几年后,我发现自己可以依靠自己的笔记了。慢慢地,我也可以将我的笔记制作成演示文稿了,我准备随时通知。
– Shivasubramanian A
19年5月10日在12:10
#6 楼
您可以从深入研究想要成为专家的语言规范开始。例如:C#
Java
评论
好的答案-例如,链接的C#规范的15.8.4节介绍了foreach的实现,并阐明了Eric Lippert引用的博客文章中描述的行为。如果有人发现自己在思考诸如“我想知道foreach的工作原理..”之类的东西,那么这将是一个开始寻找的好地方。
– Carson63000
2011年7月12日在1:06
#7 楼
获取Reflector或任何其他反编译器(因为现在需要付款),然后开始打开一些最常用的.NET库以了解内部原理。与通过C#编写的CLR之类的书结合在一起,您会学到很多(比我们大多数人的常规工作要深)。评论
我实际上是使用BitConverter类做到这一点的,并发现了IsLittleEndian系统特定的标志。
–罗伯特·哈维(Robert Harvey)
2011年7月11日在21:02
大声笑。为isLittleEndian +1
–鲁迪
2011年7月15日在10:53
#8 楼
我通过在comp.lang.c++.moderated
中呆了几年来开发了C ++的这种知识,即使当时我并没有那么努力地编写代码。我不确定我能说我怎样。我认为可以从两种知识中了解一种编程语言:
了解有关语言的琐事,并知道如何避免陷阱。
知道如何有效地解决问题。
数字2只能通过用该语言编程并查看其他人的语言来实现。代码,但是要花很多时间在讨论论坛上阅读有关该语言的信息,看看人们提出了什么样的问题以及答案是什么,就可以实现第一。 StackOverflow也是一个很好的地方。
#9 楼
丰富的知识和编程专长意味着可以在所有抽象级别上自如。即库和API
语言语义
编译器优化
编译器内部和代码生成
运行时和垃圾收集器行为
架构和指令集问题
我在过去15年中所看到的一切都表明,只有真正进入编译器和运行时,您才有机会变得精通。您可能不得不强迫自己采取步骤,并在堆栈中较低的下一个抽象层次上开始推理(和构建)软件,但这是获得专业知识的唯一方法。
我们拥有的只是语言用于抽象。您必须了解如何设计和构建编程语言,才能真正了解机器的功能。
#10 楼
阅读高级手册这不是特别深的知识。它发布在C#语言规范的8.6.4节中。您应该养成至少至少浏览一下所使用语言的规范以及所有内置库的文档的习惯。这只是一个有趣的实现细节。如果设计人员解释了为什么以这种更加动态的方式完成操作的原因,而不仅仅是检查对象是否实现Iterable,那可能会更加有趣。评论
我认为没有“掠过” C#语言规范这样的事情。
–罗伯特·哈维(Robert Harvey)
2012年5月28日15:50
@RobertHarvey:您可以浏览大多数形式语言,包括您已经知道的内容,例如运算符优先级和声明语法,并专注于意外但有用的细节,例如C#foreach或Java枚举构造函数的确切行为。
–kevin cline
2012年5月28日20:34
您可以购买该标准的带注释的版本。现在有点过时了,但是对于所覆盖语言的各个部分,注释仍然非常有趣。
–Jørgen Fogh
16 Mar 30 '16 at 10:04
评论
我认为这在开源软件大放异彩的地方尤其如此。能够一直进入框架/系统/库,这是很好的。与使用WinForms相比,当我使用Qt时,曾经有一种更好地了解框架内部的方法。除了不在特殊人群面前显得愚蠢之外,您何时需要知道此特定示例?他们白痴证明了这一点。除此之外,Effective C#,Java,C ++等系列可能还包含一些很棒的东西。埃里克·利珀特(Eric Lippert)的博客也是一个很好的来源。总的来说,我们常常不知道不知道什么,所以正如他们所说的“活一百年,学习一百年,死傻瓜”。
值得付出努力吗?我是双语人,正在尝试学习其他几种口头语言。我参加了一些数学课程,但还不够。我想学习如何像样的打网球,学会用蝶泳游泳。我想旅行更多。我想学习一些Clojure。我不希望成为一种语言的专家,拥有数学博士学位,每周在迈克尔·菲尔普斯(Michael Phelps)等游泳池度过30个小时。Lippert和Skeet的知识是由于他们投入了大量精力在一件(或几件)事情上努力,而在其他经验上则错失良机。也许要换工作?
“我能理解Eric为什么知道这一点;他在编译器团队中,所以他必须知道。” -很可能他知道这一点,因为他首先想到了这一点。我怀疑他必须“发现”它的工作原理是这样的:)
@Alex:自从我们开始实际构建C#3的实现以来,我实际上只从事C#的工作。“ foreach”规范是在此之前写的六年。我仍然每天都在探寻关于该语言的疯狂历史事物。例如,我今天了解到,对于代表来说,(((A + B)+ C)-(A + C)= A + B + C,但是((A + B)+ C)-(B + C)= A 。很奇怪!