tags:

views:

122

answers:

4

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?

+4  A: 

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";
    }
Mark Byers
Right. The only time you need to use ref for a class object is if you want to say foo = somethingElse.
ojrac
Can you elaborate please? Can you show me my code without using ref such that it will work as I have it now? I'm eager to learn!
Serg
@Sergio: Your code doesn't do anything... what do you mean by "work as I have it now"?
Mark Byers
I want the methods GetMachine/GetPersonal to set the attributes of the created 'CompleteInformation' var. Are you sure that I don't need to use Ref in this case?
Serg
Try writing a small test project to demonstrate it, but yes, that's correct: you don't need to use ref to call getters and setters.
ojrac
I don't think the OP is really wanting to create a new instance of UserInformation. Rather, he likely is wanting to modify the current instance property values. Perhaps another code sample for him that doesn't create a new instance would help the OP.
Metro Smurf
A: 

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++.

Alex Farber
+5  A: 

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.

wsanville
+3  A: 

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..

Michael Buen