可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
"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 Person
s 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.
回答2:
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);
}
回答3:
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);
回答4:
@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
回答5:
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'
回答6:
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.
回答7:
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 Person
s that can live together in the same app. And a person object can hold other person
s 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 person
s 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();
}
}