How to return the values of a List<> in C#

Asked

Viewed 4,102 times

3

I have a class Funcionario which has as attributes: CPF, Nome and Salario.

I have to create an X amount of instances of this class in a List<> and after that, return to the user the values of this list. With the code I created I did not get the values of the properties of each instance, only the namespace and the class.

aumento_funcionario.funcionario

I’d like to know why. Follow my code.

//Código da classe Program.cs
using System;
using System.Collections.Generic;
using System.Globalization;

namespace aumento_funcionarios
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Quantos funcionários serão cadastrados? ");
            int qtde_cadastros = int.Parse(Console.ReadLine());

            List<funcionario> Lista = new List<funcionario>();

            for (int i = 0; i < qtde_cadastros; i++)
            {
                Console.WriteLine("Dados do " + (i + 1) + "º funcionário: ");
                Console.Write("CPF: ");
                int cpf = int.Parse(Console.ReadLine());
                Console.Write("Nome: ");
                string nome = Console.ReadLine();
                Console.Write("Salário: ");
                double salario = double.Parse(Console.ReadLine());
                Lista.Add(new funcionario(cpf, nome, salario));
                Console.WriteLine();
            }

            for (int i = 0; i < Lista.Count; i++)
            {
                Console.WriteLine(Lista[i]);
            }

            Console.ReadLine();
        }
    }
}




//Código classe Funcionarios
    using System;
    using System.Collections.Generic;
    using System.Globalization;

    namespace aumento_funcionarios
    {
        class funcionario
        {
            public int CPF;
            public string Nome;
            public double Salario { get; private set; }

            public funcionario (int cpf, string nome, double salario)
            {
                this.CPF = cpf;
                this.Nome = nome;
                this.Salario = salario;
            }

        }
    }
  • 1

    I believe that with the answers below you have already understood your mistake in finding a solution that suits you. But by convention of the language, your classes should start with a bad letter, then rename to Funcionario https://docs.microsoft.com/pt-br/previous-versions/dotnet/netframework-4.0/ms229043(v%3dvs.100)

  • 1

    After, I wouldn’t recommend you use the whole type to store a CPF, if it doesn’t start with 0 it will probably already be a long and those who start will make it more difficult for you to consult

  • Thanks for the tips, @Leandroangelo. Like the int in this case fulfilled my need and at the moment I am not worried about the performance of my code so I ended up using the int same. But as I advance I will choose the types of variables more carefully.

  • I also have to study more about the patterns camelCase and Pascalcase. Adopting a standard at the beginning of my studies will be fundamental further forward.

4 answers

7

There are several problems in the code, some just of style. The biggest is that you are trying to convert something that is not guaranteed to be converted and this will break the application if the typing is wrong. The right is to check before using. I just closed the application to simplify, but you can send an error message and ask again for typing until a valid value is entered. In real code people create codes that do this on each item and put in function for easy use.

Note that I changed several things in the code, such as how to print, the names of things, and the use of foreach in place of for. It should be the preference, until only the for resolve. I used names inside the C nomenclature standard#.

If you used a property in a class field, why not use it at all? Or why not use the field at all if you used two of them? Keep a pattern. Including maintaining the right uppercase and lowercase pattern, which I made wrong.

You were having the list printed up. She doesn’t have an automatic printing medium that comes out as you imagine. There are endless ways to print a list, you have to assemble that item by item. And even within the item also has many ways to print each member of the list item, so you have to deal with it. Even the list was picking up every item, but not every member.

using static System.Console;
using System.Collections.Generic;

public class Program {
    public static void Main() {
        Write("Quantos funcionários serão cadastrados? ");
        if (!int.TryParse(ReadLine(), out var quantidade)) return;
        var lista = new List<Funcionario>();
        for (int i = 0; i < quantidade; i++) {
            WriteLine($"Dados do {(i + 1)}º funcionário: ");
            Write("CPF: ");
            if (!int.TryParse(ReadLine(), out var cpf)) return;
            Write("Nome: ");
            var nome = ReadLine();
            Write("Salário: ");
            if (!double.TryParse(ReadLine(), out var salario)) return;
            lista.Add(new Funcionario(cpf, nome, salario));
            WriteLine();
        }
        foreach (var item in lista) WriteLine($"CPF: {item.Cpf} - Nome: {item.Nome} - Salário: {item.Salario}");
    }
}

public class Funcionario {
    public int Cpf;
    public string Nome;
    public double Salario { get; private set; }
    public Funcionario (int cpf, string nome, double salario) {
        Cpf = cpf;
        Nome = nome;
        Salario = salario;
    }
}

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

  • My code is still very amateur, it’s true, but there’s no better way to learn than to try and miss. Thanks for the help.

  • And learned now?

  • 1

    Good once you are learning I have to say that this object printing mode is not modular, if it comes modified the employee class you have to modify punctually throughout the code where this printing, I suggest to modify the impression of the object in the class

  • 5

    @A programmer AND use ToString() for this is not correct, because in each context the impression must be in a way. Even having several printing methods in the class hurts the Principle of Single Responsibility. The printing of data should not be the responsibility of the class itself, this is something external. Alias almost every programmer fails to model this. And modular is to create modules and not to pile everything into one class. Each one doing its part. I suggest you better understand the reason for things and not repeat fallacies about software development.

  • Well, implement a large software using this type of printing and after years of millions of lines of code with printing like this, the client asks you to modify the class making this method wrong. Which refactoring will be less costly. If you put yourself so didactic because you didn’t create a system to manage that impression and put it as an answer to the question... I leave my comment here and I do not want to prolong this discussion because it leaves the context

  • 2

    The needlessness of refactoring is always the cheapest. If you don’t try to stack everything in one class you don’t need to refactor anything. Modularize is exactly put in separate modules so you don’t have to move where you shouldn’t. And the client doesn’t ask to touch any class, he tells you his need, and you go in there and change what you have to change. And it doesn’t hurt SOLID’s O if it’s separate. I did exactly what has to be done,let the consumer take the data that the object must provide and make the impression as it needs.Who will print is responsible for formatting the print,this is the correct module

Show 1 more comment

4


What happens is that when you ask to write the employee list on the console and since employees are not a simple type, but a composite object, the compiler can’t print it the way you want, I made a modification in your code so that the printing will work, then, following the logic, you can modify it as is best for you. Follows the code:

public static void Main()
{
    Console.Write("Quantos funcionários serão cadastrados? ");
        int qtde_cadastros = int.Parse(Console.ReadLine());

        List<funcionario> Lista = new List<funcionario>();

        for (int i = 0; i < qtde_cadastros; i++)
        {
            Console.WriteLine("Dados do " + (i + 1) + "º funcionário: ");
            Console.Write("CPF: ");
            int cpf = int.Parse(Console.ReadLine());
            Console.Write("Nome: ");
            string nome = Console.ReadLine();
            Console.Write("Salário: ");
            double salario = double.Parse(Console.ReadLine());
            Lista.Add(new funcionario(cpf, nome, salario));
            Console.WriteLine();
        }

        for (int i = 0; i < Lista.Count; i++)
        {
            Console.WriteLine(Lista[i]);
        }

        Console.ReadLine();
}

class funcionario
    {
        public int CPF;
        public string Nome;
        public double Salario { get; private set; }

        public funcionario (int cpf, string nome, double salario)
        {
            this.CPF = cpf;
            this.Nome = nome;
            this.Salario = salario;
        }
        public override string ToString()
        {
            return "funcionario: " + this.CPF + " " + this.Nome + " " +this.Salario + "\n";
        }
    }

}

What I did was overwrite the method of writing the employee object so that when called prints the attributes. I hope I’ve helped

  • I get it. I appreciate your help. I have to better understand how this envelope works.

  • 2

    The good thing about overwriting ToString is that you get a better view when you are in debug mode looking at the object instances.

  • 1

    I suggest you read this question here: https://answall.com/q/22913/60398 I know it’s in java, but the concept is the same

  • 3

    The ToString() It shouldn’t be used for this. It is a common mistake that people make because it seems easy to solve with it, but its function is another: https://answall.com/q/212754/101

  • Good if you don’t want to use the Tostring() method create a method in the class to make that impression. But Control her in the employee class, so in case some day you wanted to modify the class, you have to fix the printing method only there.

  • 3

    Do not do this either, because the impression is something contextual, in each situation will desire a different form, this does not make any sense. It’s even possible to have another class to take care of some of these things, but even that doesn’t make sense because you won’t consider the exact context in each case. This is something that some people taught wrong and then people repeat it as if it were true. In general who invented this was an academic and not an engineer who program in day to day, and pity that others just follow cake recipes without questioning.

  • 1

    Creating several classes of generic print types and a Factory to manage the use of them in this case seems a little like the case of using a bazooka to kill an ant...

  • 1

    And to create every possible impression in one class seems to want to use a Beetle for taxi, school van, water transport, bean bags, patrol, go around the corner, bring fuel to other vehicles, perform stunts, use as a barricade, etc. Make a real system like that, put all the necessary impressions into it and then come and tell me how it went. That’s why I always tell people to stop "object-oriented programming", in general it’s creating monsters that "know" to do everything the system needs, and complicates maintenance too much. And it’s a zone,

Show 3 more comments

1

Since the list is not of a simple type, like string, int and etc...it is necessary to print all attributes of the list.

In case it would look like this:

 for (int i = 0; i < Lista.Count; i++)
 {
      Console.WriteLine(Lista[i].Cpf);
      Console.WriteLine(Lista[i].Nome);
      Console.WriteLine(Lista[i].Salario );
 }

1

As already mentioned, you must display each property of your object Funcionario of the list.

You can use the method ForEach to display, ends up being simpler.

Lista.ForEach(funcionario =>
        {
            Console.WriteLine(funcionario.Cpf);
            Console.WriteLine(funcionario.Nome);
            Console.WriteLine(funcionario.Salario);
        });
  • This is not LINQ. It is a method of List<T>

  • Thank you for warning, while doing the answer I changed the example and forgot to change the description!

Browser other questions tagged

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