-1

I am trying to authenticate Admin Login in my AdminController, Here is what I have done so far:

[HttpPost]
public ActionResult AdminLogin(Admin admin)
    {
        Admin newAdmin = admin;
        if (ModelState.IsValid)
        {
            Admin validAdmin = _iadmin.AuthenticateAdmin(admin);
            if(newAdmin.AdminName == validAdmin.AdminName)
            {
                ViewBag.message = "Valid";
            }
        }
        return View();
    }

public Admin AuthenticateAdmin(Admin admin)
    {
        int count = 0;
        using (SqlConnection conn = new SqlConnection(connectionString))
        {

            using (SqlCommand command = new SqlCommand(query, conn))
            {
                conn.Open();
                command.Parameters.AddWithValue("AdminName", admin.AdminName);
                command.Parameters.AddWithValue("AdminPassword", admin.AdminPassword);


                SqlDataReader reader;
                reader = command.ExecuteReader();
                while (reader.Read())
                {
                    count++;
                }
                reader.Close();
            }

        }
        if (count==0)
        {
            admin.AdminName = "";
            admin.AdminPassword = "";
        }
        return admin;
    }

The problem is: when AuthenticateAdmin(admin) is executed, validAdmin and newAdmin have the save values. From my understanding, newAdmin should have the initial parameters passed by the admin and when AuthenticateAdmin runs, validAdmin should have new values set in the authenticate method.

Why is this an automatic pass by reference?

I have looked at someone asking the same question before but didn't help me much.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • 4
    Because classes use pass-by-reference semantics in c#. This is part of the language. It's unclear why that question didn't help you much, because it answers precisely what you're asking. Please explain. –  Jan 17 '20 at 15:33
  • Can you share your `AuthenticateAdmin` method? – Johnathan Barclay Jan 17 '20 at 15:37
  • 1
    Are you really asking why C# has pass by reference semantics, or why your method doesn't work? – Robert Harvey Jan 17 '20 at 15:39
  • @RobertHarvey I am asking why the way i am doing it, automatically becomes a pass by reference if I haven't explicitly mentioned it. – New_developer Jan 17 '20 at 15:42
  • @JohnathanBarclay Added it, Should've added it initially. Sorry about that. – New_developer Jan 17 '20 at 15:43
  • 2
    The difference between between structs and classes :https://stackoverflow.com/questions/9251608/are-structs-pass-by-value – Jimbot Jan 17 '20 at 15:46
  • @Amy It provides a detailed answer to my question but doesn't give an example. So the way I understood it, when I assign admin values to newAdmin, the newadmin shouldn't change when the authenticate is called on the admin. changes – New_developer Jan 17 '20 at 15:47
  • 1
    @New_developer The *question itself* contains an example of pass-by-reference semantics. *Your* question contains an example. Classes are passed by reference in c# because that is how the language works. You do not need to explicitly tell it to do so. –  Jan 17 '20 at 15:49
  • 1
    @New_developer If `Admin` is a class then it's a reference type and thus you update the object and return the a copy of the reference to that same object. If it were a struct it would copy it when passed and thus you'd return a different copy. Note that's different from how the variable is passed, which is actually by value unless the method uses the `ref` keyword. – juharr Jan 17 '20 at 15:52

2 Answers2

4

I think you are getting confused; when you pass an object to a method, you are always passing an existing object, not creating a new object with the same state. This is why they are known as reference types.

var someObject = new SomeClass();
var sameObject = SomeMethod(someObject); // still the same object
bool theSame = someObject == sameObject; // true

SomeClass SomeMethod(SomeClass someObject)
{
    SomeClass insideMethod = someObject; // still the same object
    return insideMethod; // return object passed to method
}

By "pass by reference" you may be thinking of the ref keyword. This does something different, it also passes the variable pointer:

var someObject = new SomeClass();
var sameObject = someObject; // still the same object
SomeMethod(someObject); // now a new object
bool theSame = someObject == sameObject; // false

void SomeMethod(ref SomeClass someObject)
{
    SomeClass insideMethod = someObject; // still the same object
    someObject = new SomeObject();
}
Johnathan Barclay
  • 18,599
  • 1
  • 22
  • 35
  • 4
    To be clear the first example is passing a reference type by value parameter and the second is passing a reference type by reference parameter. You can additionally pass a value type by value parameter or pass a value type by reference parameter. Here's a good blog that explains all of this https://jonskeet.uk/csharp/parameters.html – juharr Jan 17 '20 at 15:57
  • 1
    There's more background about the `ref` keyword [here](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref), including the intricacies mentioned above. – Robert Harvey Jan 17 '20 at 16:14
3

In your AuthenticateAdmin method, you're returning a reference to the same object you passed in.

If you want to return a different object, you need to do something like this:

return new Admin { AdminName="", Password="" };
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501