2012-03-04 10 views
0

これは基本的なC#の質問である必要があります。私はList<Pet>あるPetsという名前のプロパティが含まれていPersonクラスがあるとします。子オブジェクトへの新しいオブジェクトの割り当てによる子オブジェクトの更新

私はペットを更新したいのですが、そのペットを変数として取得してプロパティを操作できますが、新しいペットオブジェクトを作成して既存のペットオブジェクトに割り当てることはできません。私は "割り当てられた値は実行パスに使用されていません"という警告を受け取ります。私はこの問題を概説する非常にシンプルなコードをいくつか作成しました。

実際のコードでは、新しい子オブジェクトを使用して既存のオブジェクトを置き換えたいと考えています。下のサンプルの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値を追加し、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; } 
} 
+1

後者は動作しません。 – jason

+0

オブジェクトとオブジェクト参照の違いをまだ理解していないようです。あなたはそれについていくつかの研究をしたいかもしれません。 – usr

答えて

1

これは概念的に何をしたいのかによって異なります。一方、場合

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

:古い猫を削除してから、新しい猫:あなたは人は古い猫を処分し、新しい猫を持ってしまったことを言いたい場合、あなたはそれを行う必要があります人はまだ同じ猫を持っていますが、猫は古い猫、あなたは犬と一緒にそれをやったのと同じ方法名前を変更する必要があり、名前が変更されました:currentCatそのものですので、あなたのコードは動作しません

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

をリスト内のスポットではなく、ネコを参照します。 Jasonが提案したように、リスト内でその地点を表現する方法があれば、リストにインデックスを付けることができます。

+0

ありがとうございました。下記のJasonに述べたように、私の編集では、UpdateOrInsertメソッドを作成し、更新されたペットパラメータが変数としてメソッドに渡された場合、Person.Petsコレクションをどのように更新するのですか?私はEntity Frameworkを使用しており、コンテキストが追跡されているので、更新されたプロパティだけでオブジェクトを同じに保つ必要があります(EFで追跡されるため)。 – bigmac

1

あなたはペットを削除する必要がありますあなたは新しいペットを置き換えて追加したいと思う。

Alteratively、あなたはindexを交換したいペットの指標である

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

を言うことができます。

あなたが理解していないことは、ペットのリストは単にペットのインスタンスへの参照のリストにすぎないということです。

これらのペットインスタンスの1つへの参照を取得し、それを変数に格納し、ペットの新しいインスタンスへの参照を割り当てても、リスト内の参照の参照先は変更されません。もちろん、あなたはとにかくリストを変更していません。そのため、置き換える要素を削除して新しい要素を追加するか、置き換える要素に新しいインスタンスへの参照を直接割り当てる必要があります。

+0

ありがとうございましたJason ...これは意味をなさないようになっていますが、実際のコードで行っていることをより詳細に示すために、元々の質問を編集しました。私は "ペット"を更新することができるビジネスレイヤーにInsertOrUpdateメソッドを持たせたい(または、ユニークなId値に基づいて存在しない場合は新しいものを追加する)。私は更新の部分で混乱してきています。更新されたペットパラメータがメソッドに変数として渡された場合、Person.Petsコレクションを更新するにはどうすればよいですか?それは理にかなっていますか? – bigmac

関連する問題