How to auto increment int userid with IndexOf method with a List in C# via user input (Console Application)?

Viewed 199

My goal with the following method (Register) is to auto increment the userid when the admin fills in the user details and saves it all in a list that eventually writes the newly added user to a csv file. The csv file gets read every time the application loads. The last two methods work perfectly.

This is the method where the user input takes place and where I want to auto increment the userid:

public void Register(List<User> users)
        {
            
            int userid = users.LastIndexOf(userid);
            if (userid < users.LastIndexOf(userid))
            {
                userid++;
            }

            // Get user input
            Console.WriteLine("Enter username:");
            string username = Console.ReadLine();

            Console.WriteLine("Enter email:");
            string email = Console.ReadLine();

            Console.WriteLine("Enter password:");
            string password = Console.ReadLine();

            Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
            string userrole = Console.ReadLine();

            // Create fresh instance to save input in memory
            User user = new User(userid, username, email, password, userrole);
            
            // Adds the user to the excisting list
            users.Add(user);

            FileOperations fo = new FileOperations();
            // Calling the method from FileOperations.cs to write the List here to a CSV file
            fo.WriteUsersToCSV(users);
            
        }

I get the following error:

RegisterManager.cs(16,44): error CS1503: Argument 1: cannot convert from 'int' to 'GimpiesConsoleOOcsvListUI.User' [/home/pascalmariany/Projects/Csharp/GimpiesConsoleOOcsvList/GimpiesConsoleOOcsvListUI/GimpiesConsoleOOcsvListUI.csproj]
RegisterManager.cs(17,44): error CS1503: Argument 1: cannot convert from 'int' to 'GimpiesConsoleOOcsvListUI.User' [/home/pascalmariany/Projects/Csharp/GimpiesConsoleOOcsvList/GimpiesConsoleOOcsvListUI/GimpiesConsoleOOcsvListUI.csproj]
RegisterManager.cs(16,44): error CS0165: Use of unassigned local variable 'userid' [/home/pascalmariany/Projects/Csharp/GimpiesConsoleOOcsvList/GimpiesConsoleOOcsvListUI/GimpiesConsoleOOcsvListUI.csproj]

When I try it with the code underneath, it saves and write to the csv file, but it does not continue to auto increase the userid:

public void Register(List<User> users)
        {
           
            int userid = 3;
            userid++;

            // Get user input
            Console.WriteLine("Enter username:");
            string username = Console.ReadLine();

            Console.WriteLine("Enter email:");
            string email = Console.ReadLine();

            Console.WriteLine("Enter password:");
            string password = Console.ReadLine();

            Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
            string userrole = Console.ReadLine();

            // Create fresh instance to save input in memory
            User user = new User(userid, username, email, password, userrole);
            
            // Adds the user to the excisting list
            users.Add(user);

            FileOperations fo = new FileOperations();
            // Calling the method from FileOperations.cs to write the List here to a CSV file
            fo.WriteUsersToCSV(users);
            
        }

Output in CSV:

userid,username,email,password,userrole
1,Inkoop,inkoop@gimpies.nl,123,purchase
2,Verkoop,verkoop@gimpies.nl,123,sales
3,Beheer,beheer@gimpies.nl,123,admin
4,Bas,bas@bas.nl,123,admin
4,Tim,tim@tim.nl,123,sales

Oh, and the first 3 users are the default users! They need to stay in the CSV. That's why I start int userid = 3.

Update with implemented feedback:

I adjusted my method according to the feedback:

public void Register(List<User> users)
        {
            
            User usr = users.OrderByDescending(u => u.userid).FirstOrDefault();
            int userid = (usr == null ? 1 : usr.userid++);

            // Get user input
            Console.WriteLine("Enter username:");
            string username = Console.ReadLine();

            Console.WriteLine("Enter email:");
            string email = Console.ReadLine();

            Console.WriteLine("Enter password:");
            string password = Console.ReadLine();

            Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
            string userrole = Console.ReadLine();

            // Create fresh instance to save input in memory
            User user = new User(userid, username, email, password, userrole);
            
            // Adds the user to the excisting list
            users.Add(user);

            FileOperations fo = new FileOperations();
            // Calling the method from FileOperations.cs to write the List here to a CSV file
            fo.WriteUsersToCSV(users);
            
        }

Now the output to the csv file:

userid,username,email,password,userrole
1,Inkoop,inkoop@gimpies.nl,123,purchase
2,Verkoop,verkoop@gimpies.nl,123,sales
4,Beheer,beheer@gimpies.nl,123,admin
3,Bas,bas@bas.nl,123,sales

It adds the user, but now the last user get a different userid when the new user (Bas) is added.

Here's is my User class to be sure:

namespace GimpiesConsoleOOcsvListUI
{
    public class User
    {
        // Constructor
        public User(int userid, string username, string email, string password, string userrole)
        {
            _UserId = userid;
            _UserName = username;
            _Email = email;
            _Password = password;
            _UserRole = userrole;
        }
        private int _UserId;
        private string _UserName;
        private string _Email;
        private string _Password;
        private string _UserRole;

        public int userid
        {
            get { return _UserId; }
            set { _UserId = value; } 
        }
        public string username
        {
            get { return _UserName; }
            set { _UserName = value; }
        }

        public string email
        {
            get { return _Email; }
            set { _Email = value; }
        }

        public string password
        {
            get { return _Password; }
            set { _Password = value; }
        }

        public string userrole
        {
            get { return _UserRole; }
            set { _UserRole = value; }
        }
        
    }
}

Update 2:

I tried the suggestions from the comments below. But I now get this output in my csv file. Same as when I do Console.WriteLine to display List in memory:

userid,username,email,password,userrole
1,Inkoop,inkoop@gimpies.nl,123,purchase
2,Verkoop,verkoop@gimpies.nl,123,sales
5,Beheer,beheer@gimpies.nl,123,admin
3,Bas,bas@bas.bl,123,admin
4,Tim,tim@tim.nl,123,sales

As you can see the new added users Bas and Tim are getting userid 3 and 4. The already existing user Beheer goes from userid 3 to userid 5. So the userid++ works, but not how I want it.

The three default users (Inkoop, Verkoop and Beheer) should stay at userid 1, 2 and 3. The new users should go on from 4 and so on...

My method to register new users:

public void Register(List<User> users)
        {
            
            User usr = users.OrderByDescending(u => u.userid).FirstOrDefault();
            
            int userid = (usr == null ? 1 : usr.userid++);

            // Get user input
            Console.WriteLine("Enter username:");
            string username = Console.ReadLine();

            Console.WriteLine("Enter email:");
            string email = Console.ReadLine();

            Console.WriteLine("Enter password:");
            string password = Console.ReadLine();

            Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
            string userrole = Console.ReadLine();

            // Create fresh instance to save input in memory
            User user = new User(userid, username, email, password, userrole);
            
            // Adds the user to the excisting list
            users.Add(user);

            FileOperations fo = new FileOperations();
            // Calling the method from FileOperations.cs to write the List here to a CSV file
            fo.WriteUsersToCSV(users);
            
        }

My write to csv file method:

public void WriteUsersToCSV(List<User> users)
        {
            
            // overwrite the file each time; indicated by the `false` parameter
            using (var writer = new StreamWriter("users.csv", false))
            using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                User usr = users.OrderBy(u => u.userid).FirstOrDefault();
                // csvWriter.Configuration.HasHeaderRecord = false; // commented out as we write the whole file every time including the header
                csvWriter.WriteRecords(users);
                Console.WriteLine("New user added to users.csv");
            }
        }

I think that because of the positioning of objects in the List is affecting the userid++ somehow... I also tried to change users.Add to users.Insert(3, user). But the same result is shown. What am I missing?

2 Answers

The users variable is a List<User>. You cannot search in this list for UserId which is a property of every user. The compiler has no way to understand that the integer passed to LastIndexOf should be used to search the list for a user with that id. That's exactly the meaning of the errors shown by the compiler.

Fortunately we could use Linq for this kind of tasks. So searching a user with a particular userid is simply

 User usr = users.FirstOrDefault(u => u.UserId == 3);

this will return an User instance with that userid = 3 if it exists in the list or null if not.

But in your code you need something more. You need to know the last userid inserted (or reloaded from file) and then increment that value before assigning it to the next user. Again, in the Linq namespace we could find another method that helps us

public void Register(List<User> users)
{
   User usr = users.OrderByDescending(u => u.UserID).FirstOrDefault();
   int nextUserId = (usr == null ? 1 : usr.UserId++);
   .....

This will order the users sequence in descending UserId order, then again we take the first element of the sequence. Now it is trivial to increment the userid for the next user.

This is the answer that solved my problem:

int userid = (usr == null ? 1 : usr.userid + 1);
Related