C# 'pointer' to parent

Started by
12 comments, last by JamesLewis 15 years, 11 months ago
I've got a main game class, and I need some of the member classes to store a 'pointer' to the parent game class, I'm not sure what the syntax or terminology is here. I'm trying something like this, which doesn't work. I'm not sure why. The function below is from the Game class, and then the Worker's constructor that I'm calling. Also, and I handling the filling of the 'Workers' List correctly? From my reading so far, I'm lead to believe that I'm supposed to just keep 'new'ing that temp instance, and the GC takes care of the old ones?
public void CreateRandomGameEnvironment()
        {           

            //create 500 worker to fill the game environment
            for (int i = 0; i < 500; ++i)
            {
                Worker temp = new Worker(ref this);
                temp.Randomize(i);

                Workers.Add(temp);
            }

        }

**********

        public Worker(ref Game p)
        {
            Parent = p;
            return;
        }
Advertisement
It's called a 'reference' in C#.

Your code is almost right.

public class Worker{  Game parent;  public Worker(Game game)  {    parent = game;  }}public class Game{  public void CreateRandomGameEnvironment()  {    for (int i=0; i<500; ++i)    {      Worker temp = new Worker(this);      temp.Randomize(i);      Workers.Add(temp);    }  }}


That code should work.


The 'ref' keywork isn't needed in this case. 'ref' is used for a situation like this:

void Foo(ref int x){  x = 5; // the value that the caller passed in is modified }void Bar(int x){  x = 5; // the value that the caller passed in is NOT modified}void Main(){  int x = 1;  Bar(x);  Console.WriteLine(x.ToString()); // It's still 1  Foo(ref x);  Console.WriteLine(x.ToString()); // Now it's 5!}
In C#, classes are reference types so you do not need to use the ref keyword when passing them to methods/constructors in the manner you are. You may not pass this as a reference or output parameter, which is why you're having problems!

The same applies to your temp variable - adding it to the list only copies its reference, not an entire clone of the data.

For what its worth, the following should do what you're after:
public class Worker {	public Game Parent { get; private set; }	public Worker(Game parent) {		this.Parent = parent;	}	public void Randomize(int something) { }}public class Game {	private List<Worker> Workers;	public Game() {		this.Workers = new List<Worker>();	}	public void CreateRandomGameEnvironment() {		for (int i = 0; i < 500; ++i) {			var Temp = new Worker(this);			Temp.Randomize(i);			this.Workers.Add(Temp);		}	}}

[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]

try passing your Game object through to the Worker constructor without the ref parameter.

all objects derived from the object class are known as reference types opposed to value types like structs, ints and floats, so for most purposes you can consider them to work like pointers. So in my admittedly limited experience there is no need for the ref and out keywords in cases like this.

As for your use of the workers list it seems ok to me. The C# garbage collector is really good but its best to take things into your own hands if your working on anything serious that way you know its been disposed of rather than hoping and praying. To do this have a look at these 3 MSDN articles:

http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

Hope that helps, if not post the actual error your getting and/or some output.
"I have more fingers in more pies than a leper at a bakery!"
Thanks guys.

This is my first attempt at a C# project that isn't a simple HELLO WORLD. :) It's working now.
Quote:Original post by benryves
In C#, classes are reference types so you do not need to use the ref keyword when passing them to methods/constructors in the manner you are. You may not pass this as a reference or output parameter, which is why you're having problems!

The same applies to your temp variable - adding it to the list only copies its reference, not an entire clone of the data.

For what its worth, the following should do what you're after:
*** Source Snippet Removed ***
What's the point of the THIS in the Workers.Add line?

this.Workers.Add

"this" used in the example benry did is not really required it just implies that the Workers list you are adding to is stored as part of the object instance running the CreateRandomGameEnvrionment() method, rather than a Workers list that is a static class member. The object instance would be a Game object see your program.cs file i believe the object will be called "Game1" providing you have not changed the program.cs source.

because you will only ever have 1 Game running "this" in benry's example will always refer to the same object as the "Game1" variable.
"I have more fingers in more pies than a leper at a bakery!"
Quote:Original post by Vampyre_Dark
What's the point of the THIS in the Workers.Add line?
Purely a force of habit, I tend to prefix any class members (be they methods, properties or fields) with this. to quickly differentiate them from local variables.

There is one place where they can be required, though. Before C#3 gave us automatic properties, I would hide property member fields by giving them a lowercase name, which is also recommended for arguments. So;

class SomeClass {    private readonly int someProperty;    public int SomeProperty {        get { return this.someProperty; }    }    public SomeClass(int someProperty) {        someProperty = someProperty; // This would not work.        this.someProperty = someProperty; // This is unambiguous, so works as you'd expect.    }}
(Some people would use an m_ prefix or similar, but I believe that's frowned upon by the guidelines and I don't really go in for prefixes - other than on IInterfaces - myself).

Of course, typing this. also causes the autocomplete box to pop up, so helps if you're lazy. [wink]

[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]

Yeah that ?_ prefix Hungarian notation I think its called MS's guidelines say not to use it anymore to go for a name that is more descriptive if a little more verbose. Just out of curiosity anyone know why?
"I have more fingers in more pies than a leper at a bakery!"
Quote:Original post by fanaticlatic
Yeah that ?_ prefix Hungarian notation I think its called MS's guidelines say not to use it anymore to go for a name that is more descriptive if a little more verbose. Just out of curiosity anyone know why?


They dropped it years ago. Encoding the type of the variable inside the name of the variable causes serious problems when the type changes later on in the project.

For example, the first pass through the code might use a long integer (l prefix) for storage, but people coming through later realize it was a horrible mistake and change the type to bool (b prefix). Now we need to rename the variable everywhere it is used in code.

This topic is closed to new replies.

Advertisement