0

I created a class User, which contain simple variables as shown below:

    public class User
    {
            public string username; //Unique usernames
            public string password;
    }

I then instantiate a list of an object in another class:

    List<User> user = new List<User>();

    user.Add(new User {username = "admin", password = "123"});

How is it possible for me to retrieve the password's value by searching for the username using a foreach loop? I am probably just confused but this is what I came up with:

    foreach(var item in user)
    {
            if(item.Equals(username_input))
            {
                //I try to store the password into a string pass_check
                pass_check = item.password;
            }
    }

    if (user_input.Equals(pass_check))
    {
            Console.WriteLine("Login successful");
    }

Sorry if this seems like a dense question to anyone out there, still a beginner trying to learn!

Leon Kho
  • 97
  • 2
  • 8
  • 1
    `item.username` – user700390 Nov 10 '17 at 18:44
  • 4
    You need to compare the username as in `item.username.Equals(username_input)` Also I suggest you make those properties instead of public fields. – juharr Nov 10 '17 at 18:45
  • 2
    If you're just playing around, this is okay. But if this is intended to be used by real users, you should never store actual passwords like this! Passwords should be stored one way hashed and salted. You shouldn't store passwords in plaintext like this. – mason Nov 10 '17 at 18:50
  • put the user object in a `Dictionary` instead (if this is a common operation – pm100 Nov 10 '17 at 18:50
  • 2
    and of course, NEVER EVER store passwords – pm100 Nov 10 '17 at 18:51
  • I'm just messing around with object lists to learn more about it, but thank you for all the elaborate response and advice, guys! – Leon Kho Nov 11 '17 at 05:11

2 Answers2

0

You're pretty close..

if(item.username.Equals(username_input))

You need to check the property of the item in this case which is username.

You could even shorten it to:

foreach(var item in user)
{
  if(item.username.Equals(username_input)
    && user_input.Equals(item.password))
  {
    Console.WriteLine("Login successful");
    break; // no need to check more.. or is there?
  }               
}

You can get really fancy using Linq:

if (user.Any(i => i.username.Equals(username_input)
  && user_input.Equals(i.password))
{
  Console.WriteLine("Login successful");
}

As juharr noted in the commend, best practices for exposing values from class/objects is to use Properties not Fields..

public class User
{
  // not best practices
  public string username; 

  // best practices
  public string password { get; set; }
}
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • Not mine, but mitigated it – Patrick Artner Nov 10 '17 at 19:04
  • 1
    I don't really care about the points, if I wrote something incorrectly I'd love to know *why*. – Erik Philips Nov 10 '17 at 19:05
  • 2
    I know you're copying op's code, but I can't help but point out: while using `.Equals` to compare strings isn't exactly wrong, it's kind of unusual – BurnsBA Nov 10 '17 at 19:09
  • @BurnsBA That's is really good point. You should definitely comment on that not necessarily being best practices. – Erik Philips Nov 10 '17 at 19:11
  • 1
    Not using `String.Equals` is not really a bad practice, in fact its a better practice since method is overloaded to handle many more cases, check: https://stackoverflow.com/questions/1659097/why-would-you-use-string-equals-over – Mrinal Kamboj Nov 10 '17 at 19:14
  • 1
    @MrinalKamboj The only difference between using (that overload of) `Equals` instead of `==` here is that `Equals` will throw if the first operand is null and `==` will return the correct value in that case. In every other situation they're identical. – Servy Nov 10 '17 at 19:33
  • @Servy yes that would need null propagation, which is expected in such usage – Mrinal Kamboj Nov 10 '17 at 19:41
  • @MrinalKamboj Yes, if you used proper null propagation then you would in fact have identical behavior to using the `==` operator, instead of inferior behavior. – Servy Nov 10 '17 at 20:14
0

Even fancier:

using System.Linq;

public static class Extensions
{
    // Extension method that works on List<User> to validate user && PW
    // - returns true if user exists and pw is ok, else false
    public static bool CheckUserPassword(this List<User> users, string user_name, string pw)
    {
        // add null checks for users, user_name and pw if you are paranoid of know your customers ;o)
        return users.Any(u => u.username == user_name && u.password == pw);
    }
}

public class User
{
    public string password;
    public string username; //Unique usernames
}

internal class Program
{
    private static List<User> users = new List<User> { new User { username = "admin", password = "123" } };

    static void Main(string[] args)
    {
        // use extension method like this:
        var isValid = users.CheckUserPassword("Hello","Jeha");

        Console.WriteLine($"user 'admin' with pw '8888' => {users.CheckUserPassword("admin", "8888")}");
        Console.WriteLine($"user 'admin' with pw '123' => {users.CheckUserPassword("admin", "123")}");
        Console.ReadLine();
    }
}

Extension Methods can be executed on the this-part - in this case only on List<User>s. The Extensionmethod uses Linq to find if Any (at least 1) user of this name and pw exists.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • While extension methods can be very useful, I would not recommend them as the default way to organize one's code. – crashmstr Nov 10 '17 at 19:07