tags:

views:

138

answers:

7
class Person
{
    string name;

    public Person(string name)
    {
        this.name = name;
    }

    public void method()
    {
        Person gupta = new Person("James"); // Current Object
        Console.WriteLine(this.name);
        Person gupta1 = new Person("Peter");  // Current Object
        Console.WriteLine(this.name);
        Person gupta2 = new Person("Frank");  // Current Object
        Console.WriteLine(this.name);
    }

    static void Main(string[] args)
    {
        Person p = new Person("Jim");
        p.method();
        Console.ReadLine();
    }
}

This code produced result

Jim
Jim
Jim

However if thought this should be

James
Peter
Frank

Can somebody explain please?

+7  A: 

this refers to the current instance. When in the Main method you create an instance of the Person class you are passing Jim to the constructor which is then stored in the name field. Next you invoke the method. Inside this method you are creating multiple instances of the Person class : gupta, gupta1 and gupta2. You need to call the name field on each instance:

public void method()
{
    Person gupta = new Person("James");
    Console.WriteLine(gupta.name);
    Person gupta1 = new Person("Peter");
    Console.WriteLine(gupta1.name);
    Person gupta2 = new Person("Frank");
    Console.WriteLine(gupta2.name);
}
Darin Dimitrov
That is what I am saying here I am creating three instances. Still this is referring to the instance created with name as Jim
Nadeem
Yes you are creating three instances but you never use those instances. The local variables `gupta`, `gupta1` and `gupta2` are created but never used.
Darin Dimitrov
No, "this" still refers to Jim. You put references to your three new instances in gupta, gupta1 and gupta2.
wj32
Then i cant understand what does the statement "this refers to current onject means". As here this is always referring to same object even after creating three more objects.
Nadeem
When you call the method the current instance is the one you created in Main method and which is `Jim` : `this` refers to it.
Darin Dimitrov
That's Okay but once the method is called more instances are created inside the method. So my question is why these newly created instances are not considered as current instance.
Nadeem
Because they are new instances which don't replace the current instance. You cannot replace the current instance from within the class.
Darin Dimitrov
@Darin - Now this point clarifies the situation.
Nadeem
+3  A: 

You are using this. Which refers to the object instance you are currently in. Change the code the following and you will get what you expect.

        Person gupta = new Person("James");
        Console.WriteLine(gupta.name);
        Person gupta1 = new Person("Peter");
        Console.WriteLine(gupta1.name);
        Person gupta2 = new Person("Frank");
        Console.WriteLine(gupta2.name);
linuxuser27
+1  A: 

When you use this.name you are addressing the object itself and not the new objects that you created. (notice that you used this.name three times and got three "Jims").

So, if you want to print the names of the people you just created use gupta.name for the first one and gupta1.name etc.

other option is to hold a List<Person> and use foreach to run on the list and print the names.

Notice that there are many Persons that can live together in the same app. And a person object can hold other persons objects. when you are inside a function of one person (here its a function inside jim) the this.name will refer only to him (to jim) and not to the other persons instances inside Jim!

 class Person
{
     public string Name
     {
          get;
         protected set;
     }
    List<Person> Relatives
     {
        get;
        set;
     }

    public Person(string name)
    {
        this.Name = name;
        Relatives = new List<Person>();
    }

    public void AddRelative(Person Relative)
    {
        Relatives.Add(Relative);
    }

    public void PrintRelatives()
    {
        foreach (Person Relative in Relatives)
        {
            Console.WriteLine(Relative.Name);
        }
    }

    static void Main(string[] args)
    {
        Person jim = new Person("Jim");
        jim.AddRelative(new Person("James"));
        jim.AddRelative(new Person("Peter"));
        jim.AddRelative(new Person("Frank"));
        jim.PrintRelatives();
        Console.ReadLine();
    }
}
Adibe7
+2  A: 

"Current object" is a rather informal way of speaking. It is ok as long as you don't get confused about what it refers to.

Do not think of it as a kind of "chronological" measure - the "current object" is not the very object you last instantiated anywere. Instead, it is the instance of the class on which you called the current execution of the method.

At the time of writing "this.(...)", you don't know which instance it will be. You will now when the code is called.

Person somePerson = new Person("Lucy");
somePerson.method();

Inside this call to method, "this" will be Lucy - because the method method is being called on that particular instance of Person. The little Persons you create inside method will not affect this at all.

Further clarification:

Person somePerson = new Person("Lucy");
somePerson.method(); // inside method, "this" is Lucy.

Person somePerson = new Person("Anne");
somePerson.method(); // inside method, "this" is Anne.

Person somePerson = new Person("Sarah");
somePerson.method(); // inside method, "this" is Sarah.

Person somePerson = new Person("Emily");
somePerson.method(); // inside method, "this" is Emily.
Daniel Daranas
So this means that this will always refer to the first created instance.
Nadeem
@Nadeem - to the one at the left of the ".method()". Once you enter a particular execution of method, you already have a this reference, which will not change _inside_ method.
Daniel Daranas
@Daniel - So what you are saying is that once this reference is set it cannot be changed. Is that so?
Nadeem
@Nadeem - I added some further examples for clarification. _Inside_ method, this refers to the object you are calling method on in each case. In subsequent executions of method, this will be, in each case, a reference to a (possibly) different object - the one you are using to do that particular invocation.
Daniel Daranas
+2  A: 

When you call

Person p = new Person("Jim"); 
p.method(); 

the method() is being executed on the 'p' object... that is your 'current' object. Perhaps it is a poor choice of words.

'Current' reffers to 'the object that the method has been called on' it does not mean 'the last used object'

Radu094
+2  A: 

Maybe if you re-write your code as:

public void method()
{
    Console.WriteLine(this.name);
}

static void Main(string[] args)
{
    Person p = new Person("James"); // Current Object
    p.method();
    Person p2 = new Person("Peter");  // Current Object
    p2.method();
    Person p3 = new Person("Frank");  // Current Object
    p3.method();
    Console.ReadLine();
}

You'll better appreciate how "this" works.

Damien_The_Unbeliever
+2  A: 

@Nadeem

You start the program by calling the main method, this creates a NEW Person with the name "Jim" and the variable p points to it.

Person p = new Person("Jim");

You then call

p.method();

So method() is being called from inside p. The method 'method()' makes 3 new Person objects with the names "James", "Peter" and "Frank" but the 'current scope' is still p. You are running 'method()' from inside p.

So if you ask p 'what is your name?', p will say, quite rightly 'Jim'.

When i was studying, I sometimes found it easier to think of it like this - if I have three children and then you ask me what my name is after the birth of each one, my name is still 5arx. You're not asking my children what their name is, you're asking me.

You could revise your code to make things a bit clearer (maybe!):

//Using declarations ommitted for brevity.

public class Person{
   public Guid ID;
   public string Name;

   public Person (string _name){
      this.Name = _name;
      ID = System.Guid.NewGuid();//creates a unique identifier
   }

   public void testMethod(){
      Console.WriteLine("This code is running inside a Person object: " + this.Identify());
      Person g1, g2, g3;

      g1 = new Person("Nadeem");
      g2 = new Person("Anish");
      g3 = new Person("Frank");

      this.Identify();// this tells you which class the code is running in - ie. what 'this' means in this context.

      //These are the additional objects you created by running testmethod from inside "Jim", the first person you created.

      g1.Identify();
      g2.Identify();
      g3.Identify();

      //If you want to get really funky, you can call testMethod() on g1, g2 and g3 too.
      //the ID field should help you see what's going on internally.

   }


   public void Identify(){
      Console.WriteLine("Person: ID=" + this.ID + "Name = " + this.Name);//Use string.format in production code!
   }

   public static void main (string[] args){
      Person p = new Person ("Jim");

      p.testMethod();
   }

}   

Hope this helps,

5arx

5arx