2016-08-09 4 views
0

Почему коллекция людей имеет элементы в ней, только если я переопределяю ее в подклассах? Вот код. Если я раскомментирую переопределенные методы, тогда моя коллекция имеет 2 человека в парке.C# - почему я получаю пустую коллекцию?

public class Park : Thing 
{ 
} 

public abstract class Thing 
{ 
    public virtual List<Thing> people { get; } = new List<Thing>(); 
} 

public class PersonA : Thing 
{ 
    Thing p; 
    public string Name { get; set; } 
    public PersonA(Thing p) 
    { 
     this.p = p; 
     Name = "Marry"; 
     this.p.people.Add(this); 
    } 
    //public override List<Thing> people => p.people; 
} 

public class PersonB : Thing 
{ 
    Thing p; 
    public string Name { get; set; } 
    public PersonB(Thing p) 
    { 
     this.p = p; 
     Name = "Joe"; 
     this.p.people.Add(this); 
    } 
    //public override List<Thing> people => p.people; 
} 

А вот тестовое приложение:

Thing park = new Park(); 
park = new PersonA(park); 
park = new PersonB(park); 

Console.WriteLine(park.people.Count); 
+2

используйте отладчик и пройдите через код, и вы увидите, где вы ошибетесь. вы даже попробовали это ...? – MethodMan

+0

Ваш базовый класс имеет новый список . Таким образом, он будет пустым, если вы не отмените его. Попробуйте отладки. – AVK

+1

В конструкторах вы добавляете список членов 'p', а не собственный список классов. 'p.people' - это не тот же список, что и' this.people'. Если вы не пытаетесь выразить, что Person_has a_ вещь, ему не нужен член 'p'. – Uueerdo

ответ

1
Thing park = new Park(); 

Здесь вы инстанцировании Park объект и присваиваем его переменной, тип Thing. Все идет нормально.

park = new PersonA(park); 

Здесь вы инстанцировании PersonA, и потому, что вы передаете ваш Park объект в конструктор, конструктор добавляет себя в People инкассо Park «s. Так что коллекция теперь содержит одного человека. Опять же, до сих пор, так хорошо.

Однако вы назначаете новый объект PersonA переменной park. Это не ошибка времени выполнения, поскольку переменная имеет тип Thing, а PersonA - это Thing, но это почти наверняка логическая ошибка с вашей стороны, потому что я не могу представить себе причину, по которой вам нужна переменная с именем park, которая ссылается к человеку.

Критически важно то, что на данный момент park.People не относится к коллекции людей Park; это относится к коллекции объектов PersonA людей, которая пуста.

park = new PersonB(park); 

Теперь при вызове PersonB конструктор, вы не передавая ему Park объект; вы передаете ему объект PersonA, который вы назначили переменной park. Таким образом, конструктор PersonB добавляет себя в коллекцию PersonAPeople, в которой теперь находится один человек.

Но опять же вы назначаете результат park. Итак, теперь park содержит объект PersonB, чья коллекция People пуста. Вот почему это:

Console.WriteLine(park.people.Count); 

Печать нуля.

+0

Полезная прогулка, спасибо. Что касается вашего второго абзаца, то как работает узор декоратора. Вы добавляете декораторы к компоненту. Сначала это выглядит немного странно, но в целом это имеет смысл и является действительно полезным шаблоном. Этот пример является упрощенной проблемой, которую я использовал в гораздо большем приложении. – haosmark

+0

@haosmark Однако это все еще кажется источником вашей проблемы.Я не очень много знаю о шаблоне дизайна декоратора, но я уверен, что назначение объекта - причина, по которой вы не работаете. –

+0

@Francis Lord nah, код не работал, потому что Person возвращал свою собственную коллекцию, а не родителями. Вот почему неудобный p.people исправляет проблему. – haosmark