Update an item from a generic list to a specific item

Asked

Viewed 3,818 times

8

How do I update a specific element of a generic list by locating by ID and passing an updated object in its place, updating the name and email?

class Program
{
    static void Main(string[] args)
    {
        List<Aluno> aluno = new List<Aluno>{
            new Aluno() { AlunoId = 1, Nome = "Cláudia",Email="[email protected]" },
            new Aluno() { AlunoId = 2, Nome = "Pedro",Email="[email protected]" },
            new Aluno() { AlunoId = 3, Nome = "Eduardo",Email="[email protected]" }
        };

        Console.WriteLine("==================================");

        foreach (var item in aluno)
        {
            Console.WriteLine("ID: {0}\nNome: {1}\nEmail: {2}", item.AlunoId, item.Nome,item.Email);
            Console.WriteLine("==================================");
        }

        Console.WriteLine("\nLista Atualizada\n");

        int iElemento = 1;

        var elem = aluno.Where<Aluno>(a => a.AlunoId == iElemento).FirstOrDefault();
        int index = aluno.IndexOf(elem);

        aluno[index].Nome = "Cláudia Limeira";
        aluno[index].Email = "[email protected]";

        foreach (var item in aluno)
        {
            Console.WriteLine("ID: {0}\nNome: {1}\nEmail: {2}", item.AlunoId, item.Nome, item.Email);
            Console.WriteLine("==================================");
        }

        Console.Read();
    }
}

class Aluno
{
    public int AlunoId { get; set; }
    public string Nome { get; set; }
    public string Email { get; set; }
}

3 answers

7


I remade the code giving a more general solution, I believe you can take what you don’t need:

using static System.Console;
using System.Collections.Generic;
using System.Linq;
                    
public class Program {
    public static void Main(string[] args) {
        var alunos = new List<Aluno> {
            new Aluno() { AlunoId = 1, Nome = "Cláudia", Email = "[email protected]" },
            new Aluno() { AlunoId = 2, Nome = "Pedro",   Email = "[email protected]" },
            new Aluno() { AlunoId = 3, Nome = "Eduardo", Email = "[email protected]" }
        };
        ImprimeAlunos(alunos);
        while (true) {
            var id = 0;
            Write("Qual ID de aluno deseja modificar? (-1 para encerrar)");
            if (int.TryParse(ReadLine(), out id)) {
                if (id == -1) break;
                var alunoAchado = alunos.FirstOrDefault(x => x.AlunoId == id);
                if (alunoAchado != null) {
                    Write("Qual o novo nome? ");
                    alunoAchado.Nome = ReadLine();
                    Write("Qual o novo e-mail? ");
                    alunoAchado.Email = ReadLine();
                } else WriteLine("Id inválido tente outro");
            } else WriteLine("Id inválido tente outro");
        }
         WriteLine("Nova Lista");
        ImprimeAlunos(alunos);
    }
    
    static void ImprimeAlunos(List<Aluno> alunos) {
        WriteLine("==================================");
        foreach (var item in alunos) {
            WriteLine($"ID: {item.AlunoId}\nNome: {item.Nome}\nEmail: {item.Email}");
            WriteLine("==================================");
        }
    }
}

class Aluno {
    public int AlunoId { get; set; }
    public string Nome { get; set; }
    public string Email { get; set; }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

Note that in case you are searching using LINQ the return is the item itself, so you do not need to use index to access it. What is changed in the found item will be reflected in the student list.

In its code the code uses the Where and the FisrtOrDefault. This is redundant since the second already does what the first one does in a way that is more appropriate to the context (the first tends to be slower). Then the code gets the item. The ideal is to change it and you preferred to find its index to change by the index as reported in the previous question. Except in this case, you don’t have to. Unless the problem requires you to do this, which I doubt, but then it would be better to solve it differently (by returning the index and not the item).

Note also that I used a more modern coding style. If you have any specific questions ask for clarification or open a question if you think the topic deserves.

You can improve even more, you can validate more things, but this is the basics.

I made another version without using LINQ. I mean, I did what LINQ would do.

  • I didn’t say anything stupid when I said type by reference in my answer, right?

  • No, it’s all right.

  • Bigown, it was great, I will market as a response!!! Do you think the way I did ended up using too much unnecessary code? My idea as I passed the message was to create an instance of the student class, pass the values to the properties and then locate the element in the list and put that object in the position of the outdated element, doing this automatically, but I ended up extending the code.

  • 1

    Almost nothing at all. But I like to make it as short as possible to keep it legible. And I like to use the most modern things. Some are not available on older compilers, which may require adaptation. One of the things I would certainly do anyway at the time there were two impressions from the list, is to turn this into method to meet the DRY. Or even to meet the principle of sole responsibility.

  • 1

    There are always several ways to do it. If your exercise required doing it by the index, I would do it, but it doesn’t seem to be the case. If it required creating a new instance of Aluno and replace the old one with the new one, I would have done so. But it is not specified that in the question, I think it is free to do as you wish, so I opted for the simplest and logical.

  • @Kellysoares I saw that you changed the acceptance of the answer, you know you can only accept one answer? You can vote for all of them, but you take only one, when you take the second, you change the vote. If you hadn’t figured it out yet, take a look at all your questions and look, and you didn’t change your acceptance by accident. You can accept whatever you think is best, this is your own decision, but rest assured that you are actually accepting what you have chosen.

  • I commented about passing an updated object because I found strange the part where I had to pass properties values by properties, this example I did actually I will adapt to a code that already receives the student class with its updated properties, What I need to do is put this property on the list to make it simpler. The questions I had was to locate an item by ID and update the list with the object that already receives the updated information. But I can create a new question to end this last question of passing the object directly to the located element.

  • You talk about clicking the triangle where you accept the question as useful or the triangle that points up and you have the option below mark as answer?

  • @Kellysoares speak on the mark of check in green, can only one per your question. See the [tour]. The triangle up and p/ down, is vote, this you can vote on everything in the whole site, are not in your questions, and if you want to learn I suggest reading other questions, vote on them, vote on the answers you find useful. There is a lot of good material here to learn. Example to start: http://answall.com/questions/tagged/c%23? Sort=votes&pageSize=50

Show 5 more comments

5

To locate the item, you need to do:

var item = aluno.First(x => x.Id == 1); //Localizando o aluno com id 1

To update you:

item.Nome = "Novo nome";
item.Email = "[email protected]";

Like Aluno is a type by reference, when changing the object item, the object inside the List will also be updated.

  • Thank you Jéferson once again!

  • Thanks for the @bigown issue, I was just looking for that question.

  • I know :) .....

2

You can create a crud to take care of the list :)/

like this ó

    private List<Obj> listaDeObjetos = new List<Obj>();

    public void Add(Obj obj)
    {
        listaDeObjetos.Add(obj);
    }

    public Obj Get(int id)
    {
        return listaDeObjetos.Find(c => c.Id == id);
    }

    public void Remove(Obj obj)
    {
        listaDeObjetos.Remove(obj);
    }

    public void Update(Cart objQueVaiSerAtualizado)
    {
        var objQueVaiSerRemovido= Get(objQueVaiSerAtualizado.Id);
        Remove(objQueVaiSerRemovido);
        Add(objQueVaiSerAtualizado);
    }

as to remove an object from a list it is necessary to pass the object, so the update becomes the most "complex" of the methods.

in the update method: you call it by passing the object that will be updated, say you changed the name, which is a property of the object and such, ai vc passes the obj with the new name, inside the method you search in the list using the Get method passing the id of the object that will be updated, the get method returns the object that is in the list and the name has not been changed, with this object you pass to the remove method, that will remove this outdated object in sequence calls the add to add the updated object.

  • Thanks Evilasio and sorry for the return. Only now I could access. I liked your explanation!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.