Обучающие ссылки в C # - PullRequest
5 голосов
/ 29 октября 2009

Через пару недель, я буду преподавать классу первокурсников инженеры основные ориентиры в C # как часть их курса первого года программирования. Большинство из них никогда не программировали прежде, и им было достаточно проблем с изучением объектов, поэтому обучение ссылкам будет тяжелой битвой. Я планирую предоставить студентам множество примеров для самостоятельного изучения, но просто показ множества примеров может быть довольно ошеломляющим, если основная концепция не «щелкает».

Итак, я задам вопрос SO-сообществу: как лучше всего вы изучали ссылки? Что заставило его «щелкнуть» для вас? Есть ли какие-либо материалы, на которые я ссылаюсь, которые мне не хватает?

Мой предварительный план урока:

  1. Что такое ссылка (используя аргумент , например, Эрика Липперта)
  2. Ссылки и сборщик мусора
  3. Типы ссылок и типы значений
  4. Неизменяемые типы
  5. Передача по ссылке в сравнении с передачей по значению (и все тонкости ссылок на объекты, передаваемых по значению)
  6. Горстка неприятных примеров, которые приводят к неожиданным результатам, если вы не понимаете 1-5.

Ответы [ 8 ]

5 голосов
/ 29 октября 2009

Один из способов, который я слышал, это использовать мобильный телефон или рацию. Вы (инструктор) держите один конец и объявляете, что вы - экземпляр объекта. Вы остаетесь в одном месте (то есть в куче), в то время как студенты передают другой конец (который находится на громкой связи, если это мобильный телефон) вокруг классной комнаты.

Они могут взаимодействовать с вами посредством «ссылки», которая у них есть, но на самом деле они не имеют «вас» во владении.

3 голосов
/ 30 октября 2009
2 голосов
/ 30 октября 2009

Попробуйте объяснить ссылки цифрами , так как чистый текст иногда не доходит до большинства людей. Многие ресурсы и книги по этой теме пытаются объяснить с помощью цифр, поскольку трудно соотнести распределение только с помощью устного общения (для большинства людей это в основном вопрос концентрации внимания).

По крайней мере, попытайтесь указать, как объекты связаны друг с другом, простой пример будет простой ссылкой.

Дано:

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

class B {
   int mine = 1;
}

При создании экземпляра класса A как объекта a из некоторого контекста на следующем рисунке показано, как все это будет выглядеть в куче. Цель иллюстрации - показать, как различные объекты связаны друг с другом, и создать ментальную модель работы кучи.

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

Также попытайтесь объяснить разницу между кучей и выделением стека. Вызов метода с параметрами. Простой пример будет примерно таким:

Учитывая следующий метод:

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

Когда вы вызываете doSomething и позволяете ему это делать, в конце стек doSomething будет выглядеть примерно так, как показано ниже. Точка, показывающая, что объекты не находятся непосредственно в стеке, а просто ссылаются на объект в куче, и объекты передаются через ссылки.

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

Другим иллюстративным примером была бы иллюстрация массива, который является объектом, и многомерный массив содержит массив массивов.

2 голосов
/ 30 октября 2009

Мне нравится аналогия с URL, которая описывает различия между типами Reference и Value. Вы можете передавать URL как ссылку на некоторый контент. Вы можете изменить этот URL без изменения этого содержимого. Вы также можете получить доступ к контенту через URL, чтобы, возможно, изменить его.

Это полезная ссылка:

 http://www.yoda.arachsys.com/csharp/parameters.html
1 голос
/ 25 февраля 2012

Я бы предложил свести к минимуму использование самого термина «ссылка», поскольку он может использоваться в .net для ссылки на две совершенно разные вещи: содержимое мест хранения класса и параметры, передаваемые с помощью «ref». квалификатор. Используйте термин «ссылка на объект» для первого и «параметр ref» для второго.

При описании «ссылки на объект» я бы предложил использовать термин «идентификатор объекта». У идентификаторов объектов есть несколько вещей, которые отличают их от «адресов»:

  1. Нельзя сделать очень много вещей с помощью идентификаторов объектов. Можно проверить, является ли один пустым, проверить, равны ли два из них, скопировать один в хранилище подходящего типа или найти объект, на который ссылается один, и попросить его сделать что-нибудь. Большинство запросов на выполнение чего-либо со значением или переменной типа класса на самом деле являются запросами на выполнение чего-либо с указанным объектом. Обратите внимание, что нельзя манипулировать идентификатором одного объекта таким образом, чтобы получить идентификатор другого, как это можно сделать с адресами.
  2. Хотя система должна иметь средства для преобразования идентификаторов объектов в адреса, нет гарантии, что она будет использовать какие-либо конкретные средства для этого. Также нет никакой гарантии, что битовый шаблон, связанный с любым идентификатором объекта, не будет самопроизвольно изменяться; все, что гарантировано, это то, что если битовый шаблон изменяется, новый шаблон будет ссылаться на тот же объект, что и старый.
  3. Система отслеживает каждое место, где хранятся идентификаторы объектов. Пока существует любая копия идентификатора объекта, этот идентификатор объекта никогда не будет ссылаться ни на что, кроме экземпляра объекта, для которого он был создан. В отличие от этого, в общем, системы, которые используют адреса для вещей, не отслеживают каждое место, где адрес может быть скопирован. Возможно, что объект может перестать существовать, пока у кого-то еще есть копия его адреса, и какой-то новый объект может быть создан с тем же адресом.
1 голос
/ 30 октября 2009

Когда я изучал VB6, ссылки на самом деле меня немного смутили. Затем я попытался изучить C ++, и после работы с указателями ссылки имели для меня смысл. Мне было легче понять это с точки зрения того, что происходит на самом деле, чем понять это с точки зрения оо-концепций. Может быть, вы можете рассмотреть в своем уроке вещи под капюшоном.

1 голос
/ 30 октября 2009

Картинки и схемы.

Люди формируют мысленные образы понятий, которые они изучают, и визуальным представлением ссылок и их отношением к связанным с ними объектам является хороший способ начать. Кроме того, очень полезна визуализация объекта как содержащего член переменные (который включает в себя ссылки на другие объекты) и член методы , такие как диаграммы UML,

Позже вы можете углубиться в детали того, как на самом деле реализованы ссылки и примитивные типы, если вы чувствуете необходимость в этом. Но затяните эти обсуждения как можно дольше, поскольку люди могут увязнуть в попытках связать абстрактные понятия с деталями репрезентации, что отвлекает от изучения абстрактных понятий.

1 голос
/ 29 октября 2009

Я нашел эта статья действительно полезна для объяснения передачи параметров в C #. Статья также хорошо объясняет общие значения и ссылочные типы.

Это скорее визуальное представление, которое мне очень помогло.

...