简体   繁体   English

C#中的教学参考

[英]Teaching References in C#

In a couple of weeks, I'll be teaching a class of first-year engineers the salient points of references in C# as part of their first-year programming course. 在几周内,我将教授一类一年级工程师作为他们一年级编程课程的一部分C#的重要参考点。 Most of them have never programmed before, and had enough trouble learning objects, so teaching references is going to be an uphill battle. 他们中的大多数人以前从未编程,并且在学习对象时遇到了足够的麻烦,因此教学参考将是一场艰苦的战斗。 I plan to have lots of examples available for the students to go through on their own, but just showing a bunch of examples tends to be pretty overwhelming if the the underlying concept doesn't 'click'. 我计划让很多学生可以自己学习,但如果基础概念没有“点击”,只是展示一堆例子往往会非常压倒性。

So I'll put the question out to the SO community: what's the best way you've seen references taught? 所以我会把这个问题提交给SO社区:你看过参考文献的最佳方式是什么? What made it 'click' for you? 是什么让它“点击”给你? Is there any reference-related material that I'm missing? 是否有任何与我有关的参考资料?

My tentative lesson plan is: 我的暂定课程计划是:

  1. What is a reference (using an argument like Eric Lippert's ) 什么是参考(使用像Eric Lippert这样参数
  2. References and the Garbage Collector 引用和垃圾收集器
  3. Reference Types and Value Types 参考类型和值类型
  4. Immutable Types 不可变类型
  5. Passing by Reference versus Passing by Value (and all of the subtleties of object references being passed by value) 通过引用传递与通过值传递(以及通过值传递的对象引用的所有细微差别
  6. A handful of nasty examples that produce unexpected results if you don't understand 1-5. 如果你不懂1-5,那么一些令人讨厌的例子会产生意想不到的结果。

One way that I've heard it explained is to use a cell phone or walkie-talkie. 我听过它解释的一种方法是使用手机或对讲机。 You (the instructor) hold one end and declare that you are an object instance. 您(教师)持有一端并声明您是一个对象实例。 You stay in one place (ie. the heap) while the students pass the other end (which is on speaker phone if it's a cell phone) around the classroom. 当学生在教室周围通过另一端(如果是手机的扬声器电话)时,你会呆在一个地方(即堆)。

They can interact with you through the "reference" they have to you, but they don't really have "you" in their possession. 他们可以通过他们对你的“参考”与你互动,但他们并没有真正拥有“你”。

I like the URL analogy that describes the differences between Reference and Value types. 我喜欢描述Reference和Value类型之间差异的URL类比。 You can pass around a URL as a reference to some content. 您可以传递URL作为对某些内容的引用。 You can modify that URL without modifying that content. 您可以修改该URL而无需修改该内容。 You can also get to the content via the URL to perhaps modify the content. 您还可以通过URL访问内容,以修改内容。

This is a useful reference: 这是一个有用的参考:

 http://www.yoda.arachsys.com/csharp/parameters.html

Try to explain references with figures , as pure text sometimes don't get through to most people. 尝试用数字解释参考文献,因为纯文本有时无法传达给大多数人。 Many resources and books on the topic, do try to explain through figures as it is difficult to relate allocation through verbal communication alone (this is mostly an issue of attention span for most people). 关于这个主题的许多资源和书籍都试图通过数字来解释,因为单独通过语言交流很难将分配联系起来(这主要是大多数人关注的问题)。

At least try to point out how objects relate to each other, a simple example would be a simple reference. 至少试着指出对象如何相互关联,一个简单的例子就是一个简单的引用。

Given: 鉴于:

class A {
    B b = new B();
}

class B {
   int mine = 1;
}

When instantiating class A as object a from some context the following figure will illustrate how it will all look in the heap. 当从一些上下文将类A实例化为对象a ,下图将说明它将如何在堆中查看。 The point of the illustration is to show how the different objects relate to each other and have a mental model for how the heap works. 图示的目的是显示不同对象如何相互关联,并具有堆如何工作的心智模型。

         +-A-----+
a: *---->|       |
         |       |   +-B--------+
         | b: *--+-->|          |
         |       |   | mine: 1  |
         +-------+   |          |
                     +----------+

Also try to explain the difference between heap and stack allocation. 还试着解释堆和堆栈分配之间的区别。 Calling a method with parameters. 使用参数调用方法。 Simple example would be something like this: 简单的例子是这样的:

Given the following method: 给出以下方法:

public void doSomething(B b) {
   int doMine = b.mine + 1;
}

When calling doSomething and letting it do it's stuff, at the end doSomething 's stack will look something like below. 当调用doSomething并让它做它的东西时,最后doSomething的堆栈看起来像下面的东西。 The point showing that objects do not directly reside inside a stack, but it is just referred to an object in the heap and objects are shared through references. 显示对象不直接驻留在堆栈内的点,但它只是引用堆中的对象,并且通过引用共享对象。

whoever called doSomething *
                           |
                           v
+-doSomething-+   +-B--------+
| b: *--------+-->|          |
|-------------|   | mine: 1  |
| doMine: 2   |   +----------+
+-------------+

Another illustrative example would be illustrating an array which is an object, and a multidimensional array contains an array of arrays. 另一个说明性示例将说明作为对象的数组,并且多维数组包含数组阵列。

I found this article really useful for explaning parameter passing in C#. 我发现这篇文章对于解释C#中的参数传递非常有用。 The article also does a good job explaining value and reference types in general terms. 这篇文章也很好地解释了一般术语中的价值和参考类型。

It's more of a visual representation which helped me a lot. 它更像是一种视觉表现,对我帮助很大。

Pictures and diagrams. 图片和图表。

People form mental images of the concepts they're learning, and a visual representation of references and their relation to their associated objects is a good way to start. 人们形成他们正在学习的概念的心理图像,并且参考的视觉表示及​​其与相关对象的关系是一个好的开始方式。 Likewise, visualizing object as containing member variables (which includes references to other objects) and member methods , a la UML diagrams, is very helpful. 同样,将对象可视化为包含成员变量 (包括对其他对象的引用)和成员方法 (即UML图表)非常有用。

Later, you can delve into the details of how references and primitive types are actually implemented, if you feel the need to do so. 稍后,如果您觉得有必要,可以深入研究如何实际实现引用和基本类型的详细信息。 But delay these discussions as long as possible, as people can get bogged down in trying to pair abstract concepts to the representational details, which distracts from learning the abstract concepts. 但是要尽可能地延迟这些讨论,因为人们可能会陷入困境,试图将抽象概念与代表性细节配对,从而分散对学习抽象概念的注意力。

When I was learning VB6, references actually confused me a bit. 当我学习VB6时,参考文献实际上让我感到困惑。 Then I tried learning C++, and after dealing with pointers, references made perfect sense to me. 然后我尝试学习C ++,在处理指针后,引用对我来说非常有意义。 Understanding it from a what-is-actually-happening perspective was easier to me than understanding it from an oo-concepts perspective. 从一个实际发生的角度来理解它比从概念角度理解它更容易。 Maybe you can go over the under-the-hood stuff in your lesson. 也许你可以在课程中查看引擎盖下的内容。

I would suggest minimizing one's use of the bare term "reference" altogether, since it can be used in .net to refer to two very different things: the content of class-type storage locations, and parameters passed with a "ref" qualifier. 我建议尽量减少一个人使用的短期“引用”,因为它可以在.net中用来指代两个非常不同的东西:类型存储位置的内容,以及用“ref”限定符传递的参数。 Use the term "object reference" for the former, and "ref parameter" for the latter. 前者使用术语“对象引用”,后者使用“ref参数”。

In describing what an "object reference" is, I would suggest using the term "object ID". 在描述“对象引用”是什么时,我建议使用术语“对象ID”。 Object ID's have a few things that make them different from "addresses": 对象ID有一些使它们与“地址”不同的东西:

  1. One can't do very many things with object ID's. 使用对象ID不能做很多事情。 One can test whether one is blank, check whether two of them are equal, copy one to a storage location of suitable type, or look up the object referred to by one and ask it to do something. 可以测试一个是否为空,检查它们中的两个是否相等,将一个复制到合适类型的存储位置,或者查找一个引用的对象并要求它做某事。 Most requests to do something with a class-type value or variable are really requests to do something with the referred-to object. 大多数使用类类型值或变量执行某些操作的请求实际上是请求对引用的对象执行某些操作。 Note that one cannot manipulate an ID of one object in such a way as to get the ID of another, as one can do with addresses. 请注意,人们不能以获取另一个对象的ID的方式操纵一个对象的ID,就像使用地址一样。
  2. While the system must have a means of converting object ID's to addresses, there is no guarantee that it will use any particular means of doing so. 虽然系统必须具有将对象ID转换为地址的方法,但不能保证它将使用任何特定的方式来执行此操作。 Nor is there any guarantee that the bit pattern associated with any object ID won't spontaneously change; 也没有任何保证与任何对象ID相关的位模式不会自发地改变; all that is guaranteed is that if the bit pattern changes, the new pattern will refer to the same object as the old. 所有保证的是,如果位模式改变,新模式将引用与旧模式相同的对象。
  3. The system keeps track of every place that object ID's are stored. 系统跟踪存储对象ID的每个位置。 As long as any copy of an Object ID exists, that object ID will never refer to anything other than the object instance for which it was created. 只要存在对象ID的任何副本,该对象ID将永远不会引用除创建它之外的任何对象实例。 By contrast, in general, systems that use addresses for things do not track every single place where an address might be copied. 相比之下,一般而言,使用地址的系统不会跟踪可能复制地址的每个地方。 It's possible that an object might cease to exist while somebody still has a copy of its address, and some new object might be created with the same address. 一个对象可能不再存在,而某人仍然拥有其地址的副本,并且可能使用相同的地址创建一些新对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM