Обновление дочернего объекта путем назначения нового объекта дочернему экземпляру - PullRequest
0 голосов
/ 04 марта 2012

Это должно быть фундаментальным вопросом C #.Предположим, у меня есть класс Person, который содержит свойство с именем Pets, которое является List<Pet>.

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

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

class Program
{
  static void Main(string[] args)
  {
    var program = new Program();
    program.RunMe();
  }

  public void RunMe()
  {
    var myPerson = new Person() { Name = "John Doe" };
    var dog = new Pet() { Type = "Dog", Name = "Woofie" };
    var cat = new Pet() { Type = "Cat", Name = "Chester" };
    myPerson.Pets.Add(dog);
    myPerson.Pets.Add(cat);
    Console.WriteLine("Initial Pet Status:");
    ListPets(myPerson);

    var currentDog = myPerson.Pets.SingleOrDefault(p => p.Type == "Dog");
    currentDog.Name = "Snoopie";
    Console.WriteLine("\r\nPet Status After Updating Dog Directly (name should be 'Snoopie'):");
    ListPets(myPerson);

    var updatedCat = new Pet() { Type = "Cat", Name = "Felix" };
    var currentCat = myPerson.Pets.SingleOrDefault(p => p.Type == "Cat");
    currentCat = updatedCat; 
    //Resharper shows "Value assigned is not used in any execution path" for the currentCat
    //and the current cat is never updated
    Console.WriteLine("\r\nPet Status After Trying to Update Cat by Assigning a New Cat to existing Cat (name should be 'Felix' but it's not):");
    ListPets(myPerson);

    Console.ReadLine();
  }

  public void ListPets(Person person)
  {
    foreach (var pet in person.Pets)
    {
      Console.WriteLine(string.Format("   {0} has a {1} named {2}", person.Name, pet.Type, pet.Name));
    }
  }
}

public class Person
{
  public string Name { get; set; }
  public List<Pet> Pets { get; set; }

  public Person()
  {
    Pets = new List<Pet>();
  }
}

public class Pet
{
  public string Type { get; set; }
  public string Name { get; set; }
}

Правка для добавления значения Id в Pet и создания метода InsertOrUpdatePet (Примечание: я удалил команду Console.Writeline для краткости)

class Program
{
  static void Main(string[] args)
  {
    var program = new Program();
    program.RunMe();
  }

  public void RunMe()
  {
    var myPerson = new Person() { Name = "John Doe" };
    var dog = new Pet() { Id = 1, Type = "Dog", Name = "Woofie" };
    var cat = new Pet() { Id = 2, Type = "Cat", Name = "Chester" };
    myPerson.Pets.Add(dog);
    myPerson.Pets.Add(cat);

    var updatedCat = new Pet() { Id = 2, Type = "Cat", Name = "Felix" };
    InsertOrUpdatePet(myPerson, updatedCat);

    var currentCat = myPerson.Pets.SingleOrDefault(p => p.Type == "Cat");
  }


  public void InsertOrUpdatePet(Person person, Pet pet)
  {
    var currentPet = person.Pets.SingleOrDefault(p => p.Id == pet.Id);
    if(currentPet == null)
    {
      person.Pets.Add(pet);
    }
    else
    {
      currentPet = pet; // This doesn't work
      person.Pets.SingleOrDefault(p => p.Id == pet.Id) = pet; //This throws an error 
    }
  }

}

public class Person
{
  public string Name { get; set; }
  public List<Pet> Pets { get; set; }

  public Person()
  {
    Pets = new List<Pet>();
  }
}

public class Pet
{
  public int Id { get; set; }
  public string Type { get; set; }
  public string Name { get; set; }
}

Ответы [ 2 ]

1 голос
/ 04 марта 2012

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

var updatedCat = new Pet() { Type = "Cat", Name = "Felix" };
var currentCat = myPerson.Pets.SingleOrDefault(p => p.Type == "Cat");
myPerson.Remove(currentCat);
myPerson.Add(updatedCat);

Если, с другой стороны, у человека все еще есть та же самая кошка, но кошка была переименована, вам следует переименовать старую кошку так же, как вы сделали это с собакой:

var currentCat = myPerson.Pets.SingleOrDefault(p => p.Type == "Cat");
currentCat.Name = "Felix";

Ваш код не работает, потому что currentCat это то, что ссылается на кошку, а не на место в списке. Если вы хотите каким-то образом представить место в списке, вы можете использовать индексирование в списке, как предложил Джейсон.

1 голос
/ 04 марта 2012

Вам необходимо удалить питомца, которого вы хотите заменить, и добавить нового питомца.

Альтернативно, вы можете сказать

person.Pets[index] = new Pet() { Type = "Cat", Name = "Felix" };

где index - индекс питомца, которого вы хотите заменить.

Что вы не понимаете, так это то, что List of Pet - это просто список ссылок на экземпляры Pet.

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

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