Нужна ссылка на объект для класса CTOR (до создания объекта) - PullRequest
2 голосов
/ 21 марта 2012

Видишь?Отметьте для вопроса.

public class Person 
{
    public Int16 ID { get; private set; }
    public string Name { get; private set; }
    public List<Toy> Toys { get; private set; }
    public Person(Int16 id, string name, List<Toy> toys)
    { ID = id; Name = name; Toys = toys; } 
}
public class Toy
{
    public string Name { get; private set; }
    public Person Owner { get; private set; }
    public Toy(Person owner, string name)  
    { Owner = owner; Name = name; }
}

Проблема с человеком CTOR.Как передать игрушки человеку ctor?Игрушка нуждается в Владельце в Которе Игрушек, но этот Владелец еще не построен.

Я понимаю, что могу вывести Игрушки из Персона КТОР и сделать набор общедоступным.Предположим, вы получаете только игрушки, с которыми вы родились - частный набор;имеет цель.И я понимаю, что то, о чем я прошу, может оказаться невозможным.

Как и все, кого это действительно волнует, но Той нужно знать только имя владельца, поэтому я могу просто изменить Игрушки.

  public class Toy
  {
     private Person owner;
     private string ownerName;

     public string Name { get; private set; }
     public String OwnerName 
     { 
        get
        {
           if (!string.IsnullOrEmpty(ownerName)) return ownerName;
           elseif (owner != null) return owner.Name;
           else throw new exception("homelesstoy");
     }
     public Toy( string name, Person owner)  
     { 
         Name = name; Owner = owner;
         // new toy need to write it to DB 
     }
     public Toy( string name, string _ownerName)  
     { 
         Name = name; ownerName = _ownerName;
     }
  } 

Каким-то образом лучше.Если моя игрушка - моя машина, и у них есть мои ключи, я не хочу, чтобы они знали мой адрес.От моего имени полиция может найти меня, если машина найдена.

Ответы [ 5 ]

2 голосов
/ 21 марта 2012

Есть две возможности, о которых я могу подумать:

  • Если вы хотите, чтобы классы были такими же, как у вас сейчас, вы можете создать Персона с пустым списком игрушек и добавить игрушки, например ::

    var newPerson = new Person(id, name, new List<Toy>());
    var newToy = new Toy(newPerson, toyName);
    newPerson.Toys.Add(newToy);
    
  • Если вы хотите, чтобы список был неизменным после создания, вы должны объявить его как ReadOnlyCollection<Toy>. В этой ситуации я рекомендую использовать статический метод, который создает весь лот за одну операцию:

    public class Person 
    {
        public Int16 ID { get; private set; }
        public string Name { get; private set; }
        public ReadOnlyCollection<Toy> Toys { get; private set; }
        public Person(Int16 id, string name, List<Toy> toys)
        { ID = id; Name = name; Toys = toys; } 
    
        public static Person CreateWithToys(Int16 id, string name,
            IEnumerable<string> toyNames) // or could use “params string[]”, too
        {
            var person = new Person(id, name, null);
            var toys = new ReadOnlyCollection<Toy>(
                toyNames.Select(toyName => new Toy(person, toyName)).ToList());
            person.Toys = toys;
        }
    }
    
    [...]
    
    var jimmy = Person.CreateWithToys(47, "Jimmy",
        new[] { "Rattle", "Batman costume", "Nuclear missile" });
    
    // or, if you used “params string[]” above,
    var jimmy = Person.CreateWithToys(47, "Jimmy",
        "Rattle", "Batman costume", "Nuclear missile");
    

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

2 голосов
/ 21 марта 2012

Почему сеттер на Owner закрытый?Я могу понять вашу мысль о сеттере на Toys в классе Person.

Если вы удалите это ограничение, вы можете создать резервное хранилище (полное свойство), а затем зациклить список игрушек в Person конструктор и до item.Owner = this.

public class Toy
{
    private Person _owner = null;
    public string Name { get; private set; }
    public Person Owner { 
         get { return _owner; }; 
         set {
              if(_owner != null) throw new InvalidOperationException("No Stealing");
              _owner = value;
         }
    }
    public Toy(Person owner, string name)  
    { Owner = owner; Name = name; }
}

Это позволит вам установить Owner только один раз, и последующие вызовы установщика будут исключительными.Вам не нужно было менять конструктор, потому что вы все равно могли бы сделать:

Toy batman = new Toy(null, "Bruce");

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

Я думаю, что концептуальные детали сбивают вас с толку.

edit: забыли конструктор ...

public Person(Int16 id, string name, List<Toy> toys)
{ 
    id = ID; 
    Name = name; 

    foreach(Toy item in toys) {
        item.Owner = this;
    }

    Toys = toys; 
} 
1 голос
/ 21 марта 2012

Попробуйте создать новый конструктор Toy и изменить настройщик Person в Toy на public;

public class Toy
{
    public Person Owner { get; set; }
    public Toy(string toyName);
}

public class Person
{
    Int16 id;
    string name;
    List<Toy> toys;
    public Person(Int16 id, string name, List<Toy> toys)
    { 
        this.id = id;
        this.name = name;
        this.toys = new List<Toy>();
        this.AddToys(toys);

    }

    private void AddToys(List<Toy> toys)
    {
        foreach (var toy in toys)
        {
            this.toys.Add(toy);
            toy.Owner = this;
        }
    }
}
1 голос
/ 21 марта 2012

Вы можете передать экземпляр Person в конструктор Toy, и новая игрушка будет добавлена ​​в коллекцию Person's Toys вместо передачи коллекции Toys конструктору Person.

0 голосов
/ 21 марта 2012

Вы не можете знать владельца Toy, если вы еще не создали владельца. Вам нужно сделать Owner публичным сеттером и сменить игрушечный CTOR.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...