这应该是一个基本的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; }
}
答案 0 :(得分:1)
您需要移除要替换的宠物并添加新宠物。
另外,你可以说
person.Pets[index] = new Pet() { Type = "Cat", Name = "Felix" };
其中index
是您要替换的Pet的索引。
您不理解的是,宠物列表仅仅是对宠物实例的引用列表。
获取对这些Pet实例之一的引用并将其存储在变量中并为新的Pet实例分配引用不会更改List中任何引用所引用的位置。当然不是,你还没有修改过列表。这就是为什么要么必须删除要替换的元素,添加新元素,要么直接将新实例的引用分配给要替换的元素。
答案 1 :(得分:1)
这取决于你想在概念上做什么。如果你想说这个人摆脱了老猫并且现在有了一只新猫,你应该这样做:去除旧猫然后新猫:
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
是引用cat的东西,而不是列表中的位置。如果你想用某种方式来表示列表中的位置,你可以使用索引到列表中,就像Jason建议的那样。