This should be a fundamental C# question. Suppose I have a Person class which contains a property named Pets which is a List<Pet>.
If I want to update a pet, I can get the pet as a variable and manipulate properties on it, but I can’t seem to create a new pet object and assign it to the existing pet object. I get a “Value assigned is not used in any execution path” warning. I created some very simple code that outlines this issue.
In my real code, I want to be able to use a new child object and replace and existing object. If you can show me how I can do that with the sample updatedCat below, I would greatly appreciate it!
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; }
}
Edit to add Id value to Pet and create a InsertOrUpdatePet method
(Note: I removed the Console.Writeline command for succinctness)
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; }
}
That depends on what do you want to do conceptually. If you want to say that the person got rid of the old cat and has now a new cat, you should do that: remove the old cat and then the new cat:
If, on the other hand, the person still has the same cat, but the cat was renamed, you should rename the old cat, the same way you did it with the dog:
Your code doesn’t work, because
currentCatis something that references the cat, not the spot in the list. If you want some way to represent the spot in the list, you could use indexing into the list, as Jason suggested.