Sign in to follow this  
Daaark

C# 'pointer' to parent

Recommended Posts

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;
        }

Share this post


Link to post
Share on other sites
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!
}

Share this post


Link to post
Share on other sites
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);
}
}
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by fanaticlatic
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.
I'm not using XNA. I'm making a little sim/manager in WinForms.

Quote:
Original post by benryves
Of course, typing this. also causes the autocomplete box to pop up, so helps if you're lazy. [wink]
That box kills me sometimes. Try to type something like 's' and you get set automatically typed for you, when all you wanted was 's'.

I have a similar question, so no need for a new thread.

The workers list will be a list of all possible workers. I also have a list of companies that can hire these workers, and I want them to each have a list referencing/pointing to workers in the first list.

I also want to make another list filled with the same workers, but sorted, so that the companies can scan this list in order to find good hires. I'm wondering how to go about this.

Is this the right thing to do?

Worker temp = Parent.Workers[i];
Company[n].Workers.Add(temp);

Or maybe I want a list of iterators or something?

Share this post


Link to post
Share on other sites
So you have a list of companies and a list of workers. Then each company has a list of workers that work for that company?

Firstly, if you want to sort your list of objects by something specfic (like skill level) then have that object implement IComparable then implement the CompareTo method and make it return a comparison between the values in your object you want to compare. The following is a method out of one of my classes comparing start times of my VideoRecording objects:


#region IComparable Members
/// <summary>
/// This method is used to compare this object with another object. This method compares the start times of
/// both objects.
/// </summary>
/// <param name="obj">The object to compare this one with.</param>
/// <returns>Returns the result of the comparison.</returns>
public int CompareTo(object obj)
{
// Compare the start times
return this.StartTime.CompareTo(((VideoRecording)obj).StartTime);
}
#endregion



Then you just call Sort() on your list and it'll be sorted by whatever you specified in CompareTo.

So, you have a list of all workers (List<Worker> allWorkers) and a list of companies (List<Company> allCompanies) and you want the companies to be able to add workers to their own list of workers? Something like this:


public class Company
{
// List of company workers
public List<Worker> CompanyWorkers
{
set;
get;
}
}

public class Worker
{

}

public class SomeMainClass
{
// Lists of workers and companies
List<Company> allCompanies;
List<Workers> allWorkers;

// ....... SETUP AND OTHER CODE

// .... Inside some method
{
// This example shows the current company (however you define it) adding the currently selected worker (perhaps this is taken out of a list box or something).
currentCompany.CompanyWorkers.Add(selectedWorker);
}
}



Is that what you mean? Sorry if I've missed the point - was a little confussed by the first bit of your post.

Cheers,

James

Share this post


Link to post
Share on other sites
My game class has a list of companies and a list of workers. The companies hire workers when needed from that list. But I don't want the companies to copy that data, just 'reference' it.

Same with the second list. It's not sorting that I need help with. I want to make new lists that are 'pointers'/references to the worker objects in the main list. Does my syntax achieve that?

Share this post


Link to post
Share on other sites
OK, sorry, didn't quite grasp what you were getting at.

Quote:
Original post by Vampyre_Dark
Is this the right thing to do?

Worker temp = Parent.Workers[i];
Company[n].Workers.Add(temp);


So yeah, Company[n].Workers will now contain a 'reference' to Parent.Workers[i] at this point.

Reference types in C# are like, your objects - classes etc and then value types are the primitive types so when you pass one of your objects around like you have suggested, you're passing a pointer to that data's memory location (which I'm guessing you already suspected). What you need to be careful of here is automatic garbage collection - I can't see you coming accross this with your current code (your main list I can imagine would span the life of your application) but as soon as you lose all references to the initialy created Worker, it will be disposed.

James

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this