Question

Here's my class:

public class UserInformation
    {
        public string Username { get; set; }
        public string ComputerName { get; set; }
        public string Workgroup { get; set; }

        public string OperatingSystem { get; set; }
        public string Processor { get; set; }
        public string RAM { get; set; }
        public string IPAddress { get; set; }

        public UserInformation GetUserInformation()
        {
            var CompleteInformation = new UserInformation();

            GetPersonalDetails(ref CompleteInformation);
            GetMachineDetails(ref CompleteInformation);

            return CompleteInformation;
        }

        private void GetPersonalDetails(ref UserInformation CompleteInformation)
        {

        }

        private void GetMachineDetails(ref UserInformation CompleteInformation)
        {

        }
    }

I'm under the impression that the ref keyword tells the computer to use the same variable and not create a new one.

Am I using it correctly? Do I have to use ref on both the calling code line and the actual method implementation?

Was it helpful?

Solution

When you pass a reference type (in your case, your UserInformation class is a reference type) as a parameter, by default you are passing the pointer to the class by value, meaning the GetPersonalDetails would get its own copy of a pointer which points to the same instance of the UserInformation class.

Using the ref keyword in your example will pass the same pointer to the UserInformationinstance to the method.

So in your case, if your intent is to simple modify the properties of UserInformation, the ref keyword in not needed, since you will be modifying the actual instance from GetPersonalDetails and GetMachineDetails. However, if your intent is to instantiate a new UserInformation object from inside those methods or set the instance to null, you would need to use the ref keyword.

Jon Skeet does a great job of explaining parameter passing in this article.

OTHER TIPS

You probably don't need to use ref here. Classes are reference types, so you are already passing a reference.

Here's your code without ref and a number of other style issues fixed:

    public UserInformation GetUserInformation()
    {
        UserInformation userInformation = new UserInformation();

        updatePersonalDetails(userInformation);
        updateMachineDetails(userInformation);

        return userInformation;
    }

    private void updatePersonalDetails(UserInformation userInformation)
    {
        userInformation.FirstName = "Sergio";
        userInformation.LastName = "Tapia";
     }

    private void updateMachineDetails(UserInformation userInformation)
    {
        userInformation.MachineName = "Foobar";
    }

I'm under the impression that the ref keyword tells the computer to use the same variable and not create a new one.

Maybe you have C background. Unlike C class/struct, C# class doesn't make a copy of the whole class to the called function. If you will use struct in C#, it will make an independent copy of whole content of struct to the called function, so ref is warranted when you want to minimize the memory/runtime overhead when passing your struct data structure to your function.

If you have knowledge in C, your code above translates to:

UserInformation *CompleteInformation = new UserInformation();

GetPersonalDetails(&CompleteInformation);    

And your function that has ref translates to this:

void GetPersonalDetails(UserInformation **CompleteInformation)
{
    // you can make the CompleteInformation outside to point to new instance
}

So if you will not point CompleteInformation to new instance inside of GetPersonalDetails, no need to use ref keyword. Remove the ref keyword on calling statement and called function.

var CompleteInformation = new UserInformation();
GetMachineDetails(CompleteInformation);

private void GetPersonalDetails(UserInformation CompleteInformation)
{
    // you cannot make the CompleteInformation outside to point to new instance
}

That C# code gets translated to C as:

UserInformation *CompleteInformation = new UserInformation();

GetPersonalDetails(CompleteInformation);    

void GetPersonalDetails(UserInformation *CompleteInformation)
{
    // you cannot make the CompleteInformation outside to point to new instance
}

Hmm.. :-) still thinking how to explain my answer in whole C# terms, not making an analogy to C. Thinking..

Unlike C++, in C# passing referenced variable to a function means using the same variable. This means, you can change the variable and this change is visible to caller. ref keyword allows to change reference itself (this means, reference is passed by reference). This means, function may set reference to null or assign it to another object, and this change is visible to caller. Yes, ref should be used both by function and caller. This is better than in C++, you can see in a caller code, that parameter is passed by reference.

If you know C/C++, passing reference type to function without ref keyword is the same as * in C++. Passing reference type to function with ref is the same as ** in C++.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top