By Reference in C# and How to Get Schooled By It

WARNING: If you understand The concept of By Reference, skip the first part of this post:

So you have an object, huh? Ok well what does that mean? Basically there is a stack and a heap. When you declare an object, space is made on the stack, basically it’s a placeholder saying that there will be something to point.

    User someUser;

Now when you instatiate:

    someUser = new User();

That user Object is put on the heap and that placeholder (reference) on the stack? Well it’s given a pointer which SURPRISE points to the object on the heap. Now when you pass the object into the method, you aren’t really passing what’s on the heap. You are actually copying and passing the pointer. Inside the method, a new entry is thrown on the stack that points to the same object on the heap. This way if you change anything on the object in the method, the changes are reflected outside the method. (Say if you added items to a list in the method) Now this all changes if the object inside the method is reinitialized or repointed:

    SomeMethod(User user)
    {
        user = new User();
        user.UserName = "Sean";
    }

Remember that user we passed in? It now has nothing to do with the one in the method now. There is now a new object on the heap and “user” in the method now points to it. Why did I tell you all of this?

END REFERENCE EXPLANATION:

Say you have this:

    ...

    UserList userList = new UserList();
    SomeList list = new SomeList();
    FillListFromUserList(list, userList);

    ...

    void FillListFromUser(SomeList listToCopyTo, UserList userList)
    {
       foreach(User currentUser in userList)
       {
          listToCopyTo.Add(userList);
       }
    }

Easy, and basically at this point list should have the same items as userList. Now say list needs what’s in userList but in order by UserID. Suppose you did it like this:

    void FillListFromUser(SomeList listToCopyTo, UserList userList)
    {
       foreach(User currentUser in userList)
       {
          listToCopyTo.Add(userList);
       }

       var sorted = from user in userList
                    orderby user.UserID
                    select user;

       listToCopy = sorted.ToList();
    }

Ok so a quick check to see if list now contains items will show it does. Now say you looked at this method and thought it was a little more than needed. You decide to do this:

    void FillListFromUser(SomeList listToCopyTo, UserList userList)
    {
        listToCopyTo = userList.OrderBy(user => user.ID);
    }

Now a quick check to see if list has something in it shows that it doesn’t. But wait, what the hell? The first one worked and the second is just short hand right? Eh well the problem is how objects are passed. By reference means that it doesn’t pass the original pointer from the stack but it copies it so that there are two references on the stack that point to the same object on the heap. What does this all mean? Well both

    listToCopy = sorted.ToList();
 And
    listToCopyTo = userList.OrderBy(user => user.ID);

Have now reset the pointer for the reference in the method (listToCopyTo) making it no longer have anything to do with the list outside of it (list). The reason why it gave a false positive on the first one was that I had added to the list within, and therefor to the object the list outside points to. So the changing of the pointer:

    listToCopy = sorted.ToList();

would no longer affect the list oustide. However, in the second example I never added to the object they both pointed to before I changed the pointer on the inner. Hense why the second example had nothing in the outer list. To make matters worse I would have noticed this before if the original userList hadn’t been sorted by ID already.