Roy Triesscheijn’s Weblog

My programming world

An example of the ref keyword in C# (for structs and classes)

Posted by Roy Triesscheijn on 22nd January 2011

There is a lot of confusion about the ref keyword in C#. Many claim that it shouldn’t be used for classes, only for the very different structs. But the reference keyword can actually be very handy for both classes and structs!

The reference keyword signals .NET to pass the address of the reference to the correct memory instead of the reference itself. Now that is a bit vague, so let’s take a look at the following diagram:

I’ll first explain the scenario without using the ref keyword:

Object obj = new Object();
Change(obj);

public void Change(Object o)
{
    o = new Object();
}

First we create a new object. In our diagram this first creates the data “Reference1″ in a fresh piece of memory. This reference is like an address book and points toward a location in memory (for C people, points as in pointer). In the fresh piece of memory where “Reference1″ points we place the data for our new object. Now we pass our object to the method change. On a low level this means that a fresh piece of memory is found, the data in “Reference1″ is copied there (For the well computer versed, when a method is called, all the arguments for that method are copied and put on the stack). Let’s call this new pointer “Reference2″. This “Reference2″ at first still points at “MemoryLocation1″. However in the Change method we now create a new Object using the new keyword. This creates a new object in a fresh location in our memory. Let’s call this “MemoryLocation2″. To reflect these changes the address where “Reference2″ is pointing at is also changed, this way we keep referencing the correct object. As you can see the address in “Reference1″ is not changed, so “Reference1″ still points at “MemoryLocation1″ and “Reference2″ points at “MemoryLocation2″.

Now let’s consider what happens when we do use the reference keyword.

Object obj = new Object();
Change(ref obj);

public void Change(ref Object o)
{
    o = new Object();
}

At first we again have “Reference1″ pointing at “MemoryLocation1″. But when we pass our new object to the Change method something different happens. Instead of copying “Reference1″ the memory location of “Reference1″ is copied and put on the stack, in our diagram this is “ReferenceAddress”. When new object is created it’s again put in a fresh memory location (say “MemoryLocation3″). However since we are working with the address of “Reference1″, instead of a new reference, “Reference1″ is updated to point to “MemoryLocation3″. So the instance o inside the method change and the instance obj are now the same.

If this is still a bit fuzzy to you, here is a piece of code that should make it totally clear :) . Note that structs and classes act in the same fashion this way:


public class MyClass //public struct MyStruct looks exactly the same, but is a struct
{
    public int MyData;
    public MyClass(int data)
    {
        this.MyData = data;
    }
}
class Program
    {
        static void Main(string[] args)
        {
            MyStruct struct1 = new MyStruct(1);
            Modify(struct1);

            MyStruct struct2 = new MyStruct(2);
            ModifyRef(ref struct2);
            Console.Out.WriteLine(String.Format("struct1: {0}, struct2: {1}", struct1.MyData, struct2.MyData));
//outputs "struct1: 1, struct2: 21"

            MyClass class1 = new MyClass(1);
            Modify(class1);

            MyClass class2 = new MyClass(2);
            ModifyRef(ref class2);

            Console.Out.WriteLine(String.Format("class1: {0}, class2: {1}", class1.MyData, class2.MyData));
//outputs "class1: 1, class2: 21"
            Console.ReadLine();
        }

        static void Modify(MyStruct s)
        {
            s = new MyStruct(11);
        }
        static void Modify(MyClass c)
        {
            c = new MyClass(11);
        }
        static void ModifyRef(ref MyStruct s)
        {
            s = new MyStruct(21);
        }
        static void ModifyRef(ref MyClass c)
        {
            c = new MyClass(21);
        }
    }

Tags: , , , ,
Posted in Blog, General Coding | 2 Comments »

Computermanagement software

Posted by Roy Triesscheijn on 12th October 2009

Lately I’ve been bussy working at the Rijksuniversiteit Groningen as ‘one day a week’  systemadministrator/programmer.

One of the first jobs that was assigned to me was reorganizing a set of 14 computers. These computers run ‘exhibits’ so people interested in going to the university can see what we do. The old setup was kinda odd, all computers where attached to 4 remote controlled powerinterupters and each morning someone at the reception, or me turned on then powerinterupters and each computer turned on because “wake on power” was turned on in their bioses.

Each afternoon someone would again turn off the powerinterupters and each computer would just stop because the power ran out.

If there was something wrong with a computer, you’d just pick up your keys, keyboard and mouse and sat in front of the damn thing until it worked again.

I quickly started working on laying networkcables between all computers, setting up remote desktop configurations, configuring a sever to become a proxy/dhcp server/webserver and setting up all computers to “wake on lan.” After that the administration began, find each computers username, password and mac adress, and setting a helpful computername.

After these changes I could remote desktop to the server, and from there remote desktop to each connected computer, configure it, install new software, reboot it, etc… The proxy server blocked all websites except for the websites of the university so the computers could no longer be used for ‘bad browsing’.

There was still one thing that bothered me though, and that was not being able to see which computers where still working without logging in to each and every one of them. I also wasnt happy with still having to login in to the server to send the wake on lan packets in the morning, and shutting every computer down by login in again in the afternoon.

To overcome this problem I wrote two programs, creatively called ComputerManager and ComputerMonitor. ComputerMonitor is a small application that runs in the background and sends a “I’m alive” packet to ComputerMonitor every 2minutes, it also has a small listenserver running to listen to shutdown and reboot commands. I installed this on all 14 pc’s.

The ComputerManager program listens for those “I’m alive ” packets and keeps track of which computers have not send an “I’m alive” packet for 5 minutes and adds these to a “red list”. The computers that keep responding keep being updated in the “green list” with their last update time, computername and ip-adress.

The program also allows for saving mac adresses of computers. These mac adresses are used to wake-up all computers on 8:55 am. The program also sends a shutdown message to every computer on 6:05pm. This way my job got allot easier. Ofcourse it was allot of work at first but it was worth my effort.

As a final touch I created one more little program that can be run by an exec command in a php script. This allowed me to make a secure webpage where people other than me can only press two buttons: “Turn all on” and “Turn all off”.

I’m releasing the sourcecode of ComputerManager and Monitor to everyone. Allot is still hardcoded, and there are probably some bad design descissons here and there but it might be useful to someone. The asynchronous listen server is solid and a good learning example. There’s also allot of code dealing with win32 calls like shutdown and reboot.

The most recent version can be downloaded here

I won’t be actively updating or supporting this program since it was just written for my personal use, but if you got any questions or comments, feel free to ask.

Tags: , , , , , , , , , , , , ,
Posted in Blog, General Coding | 2 Comments »