2013-06-04 5 views
1

Был введен в понятие общего списка <>. Рассмотрим следующиеПонимание списков объектов

 // Create an instance of the Theater class. 
     this.MarcusTheater = new Theater(); 

     // Set the field values of the Theater. 
     this.MarcusTheater.Screens = new List<Screen>(); 
     this.MarcusTheater.Screen1 = new Screen(); 

     // Set the field values for Screen1. 
     this.MarcusTheater.Screen1.Lenght = 23; 
     this.MarcusTheater.Screen1.Width = 50; 

     // Add Screen1 to the Screen list. 
     this.MarcusTheater.Screens.Add(this.MarcusTheater.Screen1); 

С моей точки зрения Screen1 является временным владельцем экземпляра Screen. После добавления в список он индексируется внутри этого списка и на самом деле не является Screen1? Поскольку экземпляр объекта Screen хранится в списке экранов, могу ли я оттянуть этот объект целиком? Если да, то каков наилучший способ прокрутки списка <> экранов, чтобы найти Screen1? Я знаю, что это может показаться тривиальным вопросом, но я пытаюсь прибить основы. Заранее спасибо.

+12

Вам необходимо понять концепцию _references_, независимо от того, находятся они в списке или нет. – SLaks

+0

Да, я согласен с @SLaks, это все о ссылках – jAC

+0

Кажется странным, что объект имел бы как список «Screens», так и свойство «Screen1», так как имена предполагают избыточность. – recursive

ответ

2

Из моего понимания Screen1 временный держатель для экрана экземпляра.

Вид. Это является «держателем», но это не временный. Даже когда вы добавляете Screen1 в ScreenList, Screen1 по-прежнему действует. Вы только что скопировали ссылку на этот объект. Рисунок это:

this.MarcusTheater = new Theater(); 
    this.MarcusTheater.Screens = new List<Screen>(); 
    this.MarcusTheater.Screen1 = new Screen(); 

    // <your stuff here> 

    this.MarcusTheater.Screens.Add(this.MarcusTheater.Screen1); 
    Screen1 thisIsTheSameScreen = this.MarcusTheater.Screens[0]; 

На данный момент, и this.MarcusTheater.Screen1thisIsTheSameScreen пункт того же объекта. Мы просто передаем его ссылку.

Так что, если мы сделали что-то вроде

thisIsTheSameScreen.Lenght = 20; 

Мы были бы изменения для всех, , потому что это тот же самый объект.

После того, как его добавили в список, он будет проиндексирован в этом списке и не является действительно Screen1?

Нет. Это по-прежнему то же самое, мы просто используем ссылку.

Поскольку экземпляр объекта Screen хранится в списке экранов , могу ли я оттянуть этот объект целиком?

Несомненно, точно так же, как я сделал выше.

Если это так, что это лучший способ организовать цикл по списку <> экранов в для того, чтобы найти Screen1?

Вам нужен способ идентифицировать каждый экран, например, идентификатор или имя. Таким образом, вы можете перебрать этот список и получить тот, который вы ищете, либо используя Linq, либо просто foreach.

Я знаю, это может показаться тривиальным вопросом, но я пытаюсь гвоздь по основам. Заранее спасибо.

И вы совершенно правы. Мы все должны понимать инструменты, которые мы используем.

0

Экраны не временный экран, это единственный экземпляр. Когда вы добавляете его в список, создается указатель или ссылка на экран 1. Если вы должны были изменить экран 1 через экземпляр или список, оба экземпляра изменились бы на шаге.

Вы должны прочитать о ссылках и, возможно, указателях C++, и это должно помочь вам понять.

-2

Да, объекты являются ссылочными типами, и поэтому обе переменные указывают на один и тот же объект в памяти, есть простой способ проверить это. Вы можете использовать метод Object.ReferencesEquals, чтобы определить, ссылаются ли они на один и тот же объект.

Screen screen1 = new Screen(); 
screen1.Length = 23; 
screen1.Width = 50; 

Screen screen2 = new Screen(); 
screen2.Length = 23; 
screen2.Width = 50; 

List<Screen> screens = new List<Screen>(); 
screens.Add(screen1); 
screens.Add(screen2); 

Debug.WriteLine(Object.ReferenceEquals(screen1, screens[0])); // outputs true 
Debug.WriteLine(Object.ReferenceEquals(screen2, screens[1])); // outputs true 
Debug.WriteLine(Object.ReferenceEquals(screen1, screen2)); // outputs false 
+0

'GetHashCode' не является надежным способом проверки идентичности объекта. 'object.ReferenceEquals' - лучший метод. – recursive

+1

Это не способствует пониманию ссылок на хеширование и т. П. – DonBoitnott

+0

Хе-хе, я просто добавлял редактирование, чтобы сказать, что забыл/не заметил «ReferenceEquals». – Sean

1

Я бы предположил, что вы считаете места хранения класса (поля, параметры, элементы массива и т. Д.) Как имеющие «идентификаторы объектов». Заявление someScreen.Width = 123; не изменяется someScreen. Если до выполнения этого оператора someScreen идентифицировал объект 24,601st, который был создан с момента запуска программы, оператор попросит объект # 24601 установить его свойство Width на 123 и оставить someScreen ссылкой на объект # 24601. Если говорить someList.Add(someScreen), а someList идентифицирует объект 8,675,309, тогда объект # 8675309 будет просить добавить «объект # 24601» к себе. Обратите внимание, что фактический объект # 24601 не будет добавлен в список - просто его личность.

(Я не знаю о .NET, предоставляющем средства, с помощью которых можно было определить, какой объект был создан между объектами 24600 и 24602nd, но если создано более 24 602 объектов, должен существовать ровно один такой объект; во время этого запуска программы этот объект никогда не может быть чем-то другим, кроме 24,601-го объекта, и ни один другой объект никогда не может быть 24,601-м, если гипотетически предположить, что конкретный объект является созданным 24601-м, тогда «объект # 24601 "может в этом гипотетическом контексте использоваться для ссылки на объект, о котором идет речь.)